日常防忘:CS224n 第六讲(依存分析)第七讲(tensorflow入门)

本文介绍了依存分析的基本概念,包括动态编程法、图算法和基于转换的方法。接着,文章转向TensorFlow入门,讲解了变量、占位符、数学操作节点以及如何构建和执行计算图。最后,探讨了TensorFlow中的变量初始化、损失计算和梯度下降等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上下文无关语法:

依存句法结构:通过找到句子中每个词所依赖的结构来描述句子结构

Catalan数:

完整的语言学以树库的形式标注数据,

依存树

短语结构语法

依存句法的思想是:一个句子模型,我们有一个词法项之间的关系或者词之间的关系,只有词法项之间是二元的不对称关系

泛依存(universal dependencies)

依存距离

投影依存树:如果一个依存树是完全嵌套的,则被称为投影依存树,可以把它投射到一个平面上,然后得到一个嵌套关系。

正确外位:

依存分析的方法

动态编程法

图算法:MST算法(最小生成树算法)

确定型依存句法分析

基于转换的依存分析方法

基于弧标准转换的依存分析

root 堆,任意句子开始分析时都放在这个堆栈上,堆栈的顶端在右面,

缓冲:就是要处理的句子,缓冲的左端为顶部,因为要拿掉无用的词,所以它们的顶部就是它们的交界点

三种操作:shift、left-arc、right-arc

shift:取缓冲区顶部词,然后把它放到堆栈顶部,然后在shift一次,再取缓冲顶部的词挪到堆顶部,

对堆而言,最右是顶部,
对缓冲而言,最左是顶部

left-arc、right-arc:通过在左侧或右侧添加词作为独立项来做出附加判断

left-arc:规定堆中的第二个顶部元素是堆的顶部元素的独立项,left-arc取走此独立项(I 是 ate 的独立项)

right-arc:规定堆的顶部元素是堆的第二顶部元素的一个独立项,right-arc取走此顶部项(fish 是顶部项),并增加一个弧

最终想要达到的状态:堆里只有一个root,缓冲为空

在这里插入图片描述
在这里插入图片描述

竖线表示附加元素到列表的操作

依存分析的评估

准确性测量

UAS方法:仅看箭头忽略标签,未标记准确率
LAS:使用标签,并且规定只有当标签正确时你的结果才是正确的。标记性准确分数

No Search模型

第七讲 tensorflow入门

节点类型:

变量将成为输出其当前值得有状态节点,所有节点都是操作

占位符是那些在执行时间才会接收值的节点

数学操作节点:

代码:

用变量和占位符建立一个图

在这里插入图片描述
把图部署到会话(session),即执行环境上

tf.initialize_all_variable:将之前调用的所有变量初始化

在这里插入图片描述
训练模型

定义损失:

使用占位符来表示标签,作为我们在执行时喂给的数据,

在这里插入图片描述
计算梯度:

先创建一个优化器对象,

tensorflow计算梯度的工作方式是:

每一个图节点都有一个附加的梯度操作,都有相对于输入预先构建的输出梯度,所以,当我们在计算我们的交叉熵相对于所有的参数的梯度时,通过图使用链式法则和利用反向传播计算是非常简单的

在这里插入图片描述
迭代学习:

在这里插入图片描述

线性回归:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import tensorflow as tf
import matplotlib
matplotlib.use('TKAgg')
from matplotlib import pyplot as plt

'''
good ole linear regression : find the best linear fit to our data
'''

def generate_dataset():
    # data is generated by y = 2x +e  (人工生成数据)
    # where 'e' is sampled from a normal distribution(正态分布)
    x_batch = np.linspace(-1,1,101)
    y_batch = 2 * x_batch + np.random.randn(*x_batch.shape) * 0.3
    return x_batch,y_batch

# 线性回归通过图实现,所以先定义流式图
def linear_regression():
    x = tf.placeholder(tf.float32 , shape=(None,), name = 'x')  # 形状为none 意味着可以动态的改变每一批次数据的数量,然后把它们送进网络中
    y = tf.placeholder(tf.float32 , shape=(None,), name = 'y')  # 标签 y

    with tf.variable_scope('lreg') as scope:   # 定义变量作用域,命名为lreg(线性回归)
        w = tf.Variable(np.random.normal(),name = 'W')  # 初始化w
        y_pred = tf.multiply(w,x)

        loss = tf.reduce_mean(tf.square(y_pred - y))
    return x,y,y_pred,loss

def run():
    x_batch , y_batch = generate_dataset()

    x,y,y_pred,loss = linear_regression()
    optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    init = tf.global_variables_initializer()  # 初始化变量
    with tf.Session() as session:
        session.run(init) # 初始化变量

        feed_dict = {x : x_batch,y : y_batch}
        for _ in range(30):
            loss_val,_ = session.run([loss,optimizer],feed_dict)
            print('loss:',loss_val.mean())

            y_pred_batch = session.run(y_pred,{x : x_batch})

    plt.figure(1)
    plt.scatter(x_batch,y_batch)
    plt.plot(x_batch,y_pred_batch)
    plt.savefig('plot.png')
    plt.show()

if __name__ == '__main__':
    run()

Word2vec

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import math
import numpy as np
import tensorflow as tf

from utils import *

'''
consider the following sentence:
'the first cs224n homework was a lot of fun'

with a window size of 1 , we have the dataset:
([the , cs224n],first),([lot , fun],of) ....

remember that skipgram tries to predict each context word from its target word,and so the task becomes to predict 
'the' and 'cs224n' from first, 'lot' and 'fun' from 'of' and so on.

our dataset now becomes:
(first,the),(first,cs224n),(of,lot),(of,fun)....

'''

# let's define some constants first

batch_size = 128
vocabulary_size = 50000
embedding_size = 128   # Dimension of the embedding vector.
num_sampled = 64       #number of negative examples to sample


'''
load_data loads the already preprocessed training and val data

train data is a list of (batch_input,batch_labels) pairs.
val data is a list of all validation inputs.
reverse_dictionary is a python dict from word index to word
'''

train_data,val_data,reverse_dictionary = load_data()
print('number of training examples:',len(train_data * batch_size))
print('number of validation examples:',len(val_data ))


def skipgram():
    batch_inputs = tf.placeholder(tf.int32,shape = [batch_size,])    # 占位 shape为128 * _
    batch_labels = tf.placeholder(tf.int32, shape=[batch_size,1 ])   # 占位 shape为128 * 1
    val_dataset = tf.constant(val_data, dtype = tf.int32)   # 为验证集创建一个常量,因为它们不会发生变化

    # 创建作用域 定义模型
    with tf.variable_scope('word2vec') as scope:
        embeddings = tf.Variable(tf.random_uniform([vocabulary_size,  # 创建所有数据的嵌入层 :大小为50000 * 128  ,所有数据的嵌入层
                                                    embedding_size],
                                                   -1.0,1.0))
        # random_uniform返回一个矩阵,矩阵形状为[vocabulary_size,embedding_size]

        batch_embeddings = tf.nn.embedding_lookup(embeddings,batch_inputs)   # 每批测试集数据的嵌入层
        # 用batch_inputs中对应的值去找embeddings中对应的行,形成矩阵并返回

        # 定义权重
        weights = tf.Variable(tf.truncated_normal([vocabulary_size,   # 截断正态分布
                                                   embedding_size],
                                                  stddev = 1.0 / math.sqrt(embedding_size)))  # 标准差
        biases = tf.Variable(tf.zeros([vocabulary_size]))  # 偏差

        # 损失函数 (tf.nn.nce_loss )求平均值 得到最终的损失函数,因为损失需要的是一个批次大小的损失值
        loss = tf.reduce_mean(tf.nn.nce_loss(weights = weights,  # 权重 50000 * 128
                                             biases = biases,    # 偏差 50000 * 50000 的全零矩阵
                                             labels = batch_labels,
                                             inputs = batch_inputs,
                                             num_sampled = num_sampled,  # 采样出的负样本的个数,即查找64个不属于我们的数据集的词,这些词都是噪声词
                                             num_classes = vocabulary_size))

        # 对词向量规范化
        norm = tf.sqrt(tf.reduce_mean(tf.square(embeddings),1,keep_dims = True)) # 沿着行计算均值,维度不变,50000*128
        normalized_embeddings = embeddings / norm  # 50000*128,矩阵内各个元素相除

        val_embeddings = tf.nn.embedding_lookup(normalized_embeddings,val_dataset)  # 验证集的嵌入层,余弦相似度
        # 比较词向量和验证集词向量的余弦相似度
        similarity = tf.matmul(val_embeddings,normalized_embeddings,transpose_b = True)  # normalized_embeddings在乘法之前进行转置


        return batch_inputs,batch_labels,normalized_embeddings,loss,similarity



def run():
    batch_inputs,batch_labels,normalized_embeddings,loss,similarity = skipgram()
    optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
    # 变量运行前必须做初始化操作
    init = tf.global_variables_initializer()  # 初始化
    with tf.Session() as sess:
        session.run(init)  # 初始化

        average_loss = 0.0

        # 一步处理一批数据,batch_size = 128, 循环一次换一批数据?
        for step,batch_data in enumerate(train_data):  # enumerate将其组成一个索引序列,利用它可以同时获得索引和值,返回的是一个enumerate对象
            inputs,labels = batch_data
            feed_dict = {batch_inputs : inputs , batch_labels : labels}  # 输入当前正在循环的数据的input和label

            _,loss_val = session.run([optimizer,loss],feed_dict)  # 输入数据,优化函数和损失函数运行程序计算本批数据的损失值
            average_loss += loss_val  # 累加损失值

            if step % 1000 == 0:
                if step > 0:
                    average_loss /= 1000
                print('loss at iter',step,':',average_loss)
                average_loss = 0

            if step % 5000 == 0:  # 迭代5000次
                sim = similarity.eval()   # 等价于对similarity调用session.run并取出它

                # 对验证集上的每个词 将会找到top_k个与它相近的词
                for i in xrange(len(val_data)):  # xrange用法同range,
                    top_k = 8
                    nearest = (-sim[i,:]).argsort()[1:top_k + 1]  # 根据大小的值进行排序,
                    # 第一个词是与它最相近的,也就是它本身,因为我们想得到与它最相近的8个词,因此写到top_k+1
                    print_closest_words(val_data[i],nearest,reverse_dictionary)

        finally_embeddings = normalized_embeddings.eval()  # 等价于调用session.run,传入并取出值

余弦相似度

余弦距离,也称为余弦相似度,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似

https://blog.youkuaiyun.com/zz_dd_yy/article/details/51926305

用到的函数语法

在TensorFlow的世界里,变量的定义和初始化是分开的,所有关于图变量的赋值和计算都要通过tf.Session的run来进行。想要将所有图变量进行集体初始化时应该使用tf.global_variables_initializer。

tensorflow在实际的运行时,启动一个session,程序才会真正的运行。

定义图变量

tf.Variable(initial_value, trainable=True, collections=None, validate_shape=True, name=None)

主要在于一些可训练变量(trainable variables),比如模型的权重(weights,W)或者偏执值(bias)

只有第一个参数是必需的,即必须提供初始值

在这里插入图片描述

tf.placeholder

placeholder()函数是在神经网络构建graph的时候在模型中的占位(不确定输入什么),此时并没有把要输入的数据传入模型,它只会分配必要的内存。
一般配合feed_dict使用,训练的时候实时地提供数据,run()执行时才会提供数据。

等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。

不必指定初始值,可在运行时,通过 Session.run 的函数的 feed_dict 参数指定

tf.placeholder(
    dtype,
    shape=None,
    name=None
)

参数:
dtype:数据类型。常用的是tf.float32,tf.float64等数值类型
shape:数据形状。默认是None,就是一维值,也可以是多维(比如[2,3], [None, 3]表示列是3,行不定)
name:名称

tf​.​constant​

tf​.​constant​(​value​,​ dtype​=​None​,​ shape​=​None​,​ name​=​’Const’​,​ verify_shape​=​False)

value:是一个必须的值,可以是一个数值,也可以是一个列表;可以是一维的,也可以是多维的。
dtype​:数据类型,一般可以是tf.float32, tf.float64等
shape:表示张量的“形状”,即维数以及每一维的大小
name: 可以是任何内容,只要是字符串就行
verify_shape:默认为False,如果修改为True的话表示检查value的形状与shape是否相符,如果不符会报错。

如果指定了第三个参数,当第一个参数value是数字时,张量的所有元素都会用该数字填充
而当第一个参数value是一个列表时,注意列表的长度必须小于等于第三个参数shape的大小(即各维大小的乘积),否则会报错,这是因为函数会生成一个shape大小的张量,然后用value这个列表中的值一一填充shape中的元素。
而如果列表大小小于shape大小,则会用列表的最后一项元素填充剩余的张量元素

tf.variable_scope

tf.variable_scope(): 可以让变量有相同的命名,包括tf.get_variable得到的变量,还有tf.Variable变量

它返回的是一个用于定义创建variable(层)的op的上下文管理器。

可变范围允许创建新的variable并分享已创建的variable,同时提供检查,不会意外创建或共享。

name_or_scope:string或VariableScope:要打开的范围。
default_name:如果name_or_scope参数为None,则将使用默认名称,此名称将被唯一。 如果提供了name_or_scope,它将不会被使用,因此它不是必需的,可以是None。
值:传递给op函数的Tensor参数列表。

初始化器:此范围内的变量的默认初始化程序。
regularizer:此范围内的变量的默认正则符。
caching_device:此范围内的变量的默认缓存设备。
partitioner:此范围内变量的默认分区。
custom_getter:此范围内变量的默认定制getter。

重用reuse:当reuse为False或者None时(这也是默认值),同一个tf.variable_scope下面的变量名不能相同;当reuse为True时,tf.variable_scope只能获取已经创建过的变量。
简而言之,reuse=False时,tf.variable_scope创建变量;reuse=True时,tf.variable_scope获取变量。

dtype:在此范围中创建的变量类型(默认为传递范围中的类型,或从父范围继承)

tf.random_uniform()

random_uniform(
    shape,
    minval=0,
    maxval=None,
    dtype=tf.float32,
    seed=None,
    name=None
)

从均匀分布中输出随机值。
生成的值在该 [minval, maxval) 范围内遵循均匀分布.下限 minval 包含在范围内,而上限 maxval 被排除在外。
对于浮点数,默认范围是 [0, 1)。对于整数,至少 maxval 必须明确地指定。
在整数情况下,随机整数稍有偏差,除非 maxval - minval 是 2 的精确幂。对于maxval - minval 的值,偏差很小,明显小于输出(2** 32 或者 2**64)的范围。

参数:

shape:一维整数张量或 Python 数组.输出张量的形状.
minval:dtype 类型的 0-D 张量或 Python 值;生成的随机值范围的下限;默认为0.
maxval:dtype 类型的 0-D 张量或 Python 值.要生成的随机值范围的上限.如果 dtype 是浮点,则默认为1 .
dtype:输出的类型:float16、float32、float64、int32、orint64.
seed:一个 Python 整数.用于为分布创建一个随机种子.查看 tf.set_random_seed 行为.
name:操作的名称(可选).

返回值:

用于填充随机均匀值的指定形状的张量.

可能引发的异常:

ValueError:如果 dtype 是整数并且 maxval 没有被指定.

embedding_lookup

tf.nn.embedding_lookup(embedding, inputs)

embedding是一个词典维度x词向量维度的矩阵,每一行代表一个词的词向量,列的索引值代表词在字典中的索引值。

inputs是已经根据字典转化为向量的一个列表。

embedding_lookup就是根据inputs中的向量,即该词在字典中的索引值,在embedding中找到对应行,读取该行,也就是这个词的词向量。

**简单的讲就是根据input_ids中的id,寻找embedding中的对应元素。**比如,input_ids=[1,3,5],则找出embedding中下标为1,3,5的向量组成一个矩阵返回。

需要注意的细节是返回的tensor的dtype和传入的被查询的tensor的dtype保持一致;和input的dtype无关。

tf.truncated_normal

tf.truncated_normal(shape,mean,stddev)

shape表示生成的张量维度,
mean表示均值,
stddev是标准差。

该函数产生正太分布。均值和标准差是自己设定的。

这是一个截断产生正太分布的函数,就是说产生正太分布的值如果与均值的差值大于两倍的标准差,那么就重新生成。和一般的正太分布的产生随机数据比较起来,这个函数产生的随机数与均值的差距不会超过两倍的标准差,但是一般的别的函数可能会出现这种情况。

tf.reduce_mean

reduce_mean(input_tensor,
axis=None,keep_dims=False,name=None,reduction_indices=None)

用于计算张量tensor沿着指定的数轴(tensor中的某一维度)上的平均值,主要用于降维或者计算tensor(图像)的平均值。

input_tensor:输入的tensor

axis:指定的轴,axis=0沿列进行求均值,axis=1沿行进行求均值,若不指定,则计算所有元素的均值

keep_dims:是否降维度,默认为False,输出结果会降低维度;若设置为True,输出的结果保持输入tensor的形状

name:操作的名称

类似的函数还有:

*tf.reduce_sum:计算tensor指定轴方向上的元素的累加和

*tf.reduce_max:计算tensor指定轴方向上的元素的最大值

*tf.reduce_all:计算********元素的逻辑和(and运算)

*tf.reduce_any:计算********元素的逻辑或(or运算)

tf.nn.nce_loss

def nce_loss(weights, biases, inputs, labels, num_sampled, num_classes,
             num_true=1,
             sampled_values=None,
             remove_accidental_hits=False,
             partition_strategy="mod",
             name="nce_loss")

假设nce_loss之前的输入数据是K维的,一共有N个类,那么

weight.shape = (N, K)
bias.shape = (N)
inputs.shape = (batch_size, K)
labels.shape = (batch_size, num_true)
num_true : 实际的正样本个数
num_sampled: 采样出多少个负样本
num_classes = N

sampled_values: 采样出的负样本,如果是None,就会用不同的sampler去采样。待会儿说sampler是什么。
remove_accidental_hits: 如果采样时不小心采样到的负样本刚好是正样本,要不要干掉
partition_strategy:对weights进行embedding_lookup时并行查表时的策略。TF的embeding_lookup是在CPU里实现的,这里需要考虑多线程查表时的锁的问题。

enumerate

enumerate()是python的内置函数

enumerate在字典上是枚举、列举的意思

对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值

enumerate多用于在for循环中得到计数

feed_dict

在运行程序的时候我们用feed_dict的方式把具体的值提供给placeholder,达到了给graph提供input的目的。

如feed_dict={y:3},即表示把3赋值给y,当次计算有效。

feed_dict的作用是给使用placeholder创建出来的tensor赋值。
其实,他的作用更加广泛:feed 使用一个值(不能是tensor,可以是tensor.eval()临时替换一个 op 的输出结果。 你可以提供 feed 数据作为 run() 调用的参数。 feed 只在调用它的方法内有效, 方法结束,feed 就会消失。

session

会话:运行计算图的类,使用默认注册的图(也可以手动指定计算图),一个会话只能运行一个计算图

xrange

用法与range完全相同,所不同的是生成的不是一个数组,而是一个生成器

>>> range(5) 
[0, 1, 2, 3, 4] 
>>> xrange(5)
xrange(5)
>>> list(xrange(5))
[0, 1, 2, 3, 4]

tf.matmul

tf.matmul (a, b, transpose_a=False,
                        transpose_b=False, 
                       adjoint_a=False,
                        adjoint_b=False,
                      a_is_sparse=False, 
                      b_is_sparse=False,
                    name=None) 

tf.matmul()将矩阵a乘以矩阵b,生成a * b。

a: 一个类型为 float16, float32, float64, int32, complex64, complex128 且张量秩 > 1 的张量。

b: 一个类型跟张量a相同的张量。

transpose_a: 如果为真, a则在进行乘法计算前进行转置。
transpose_b: 如果为真, b则在进行乘法计算前进行转置。
adjoint_a: 如果为真, a则在进行乘法计算前进行共轭和转置。
adjoint_b: 如果为真, b则在进行乘法计算前进行共轭和转置。
a_is_sparse: 如果为真, a会被处理为稀疏矩阵。
b_is_sparse: 如果为真, b会被处理为稀疏矩阵。
name: 操作的名字(可选参数)

返回值: 一个跟张量a和张量b类型一样的张量且最内部矩阵是a和b中的相应矩阵的乘积。

注意:
(1)输入必须是矩阵(或者是张量秩 >2的张量,表示成批的矩阵),并且其在转置之后有相匹配的矩阵尺寸。
(2)两个矩阵必须都是同样的类型,支持的类型如下:float16, float32, float64, int32, complex64, complex128。

tf.multiply

tf.multiply(x, y, name=None)

x: 一个类型为:half, float32, float64, uint8, int8, uint16, int16, int32, int64, complex64, complex128的张量。

y: 一个类型跟张量x相同的张量。

返回值: x * y element-wise.

注意:

(1)multiply这个函数实现的是元素级别的相乘,也就是两个相乘的数元素各自相乘,而不是矩阵乘法,注意和tf.matmul区别。
(2)两个相乘的数必须有相同的数据类型,不然就会报错。

eval

  1. 字符串转换成列表
  2. 字符串转换成字典
  3. 字符串转换成元组
  4. 将字符串转换成表达式执行

eval函数就是实现list、dict、tuple与str之间的转化
str函数把list,dict,tuple转为为字符串

argsort

argsort函数返回的是数组从小到大排序后对应的数组索引

>>> x = np.array([[3,5,1],[6,2,4]])
>>> x
array([[3, 5, 1],
       [6, 2, 4]])
>>> np.argsort(x) #默认按行比较
array([[2, 0, 1],
       [1, 2, 0]], dtype=int64)
 
>>> np.argsort(x,axis = 0) #按列比较
array([[0, 1, 0],
       [1, 0, 1]], dtype=int64)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值