SquareFace Blog


  • 首页

  • 关于

  • 标签

  • 归档

  • 搜索

evaluate(input_sentence)

发表于 2019-08-15
字数统计: 430 | 阅读时长 ≈ 2

详细的记录 evaluate函数的实现。
解决报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ValueError                                Traceback (most recent call last)
<ipython-input-44-2ec1176683f0> in <module>
----> 1 translate(u'Estoy trabajando.')

<ipython-input-43-4364cc5c7981> in translate(input_sentence)
49
50 def translate(input_sentence):
---> 51 results, input_sentence, attention_matrix = evaluate(input_sentence)
52
53 print("Input: %s" % (input_sentence))

<ipython-input-43-4364cc5c7981> in evaluate(input_sentence)
20 decoding_input = tf.expand_dims([out_tokenizer.word_index['<start>']], 0)
21 for t in range(max_length_output):
---> 22 predictions. decoding_hidden, attention_weights = decoder(decoding_input, decoding_hidden, encoding_outputs)
23 attention_weights = tf.reshape(attention_weights, (-1,))
24 attention_matrix[t] = attention_weights.numpy()

ValueError: too many values to unpack (expected 2)

注意看predictions 后面的标点符号

接收的是一个文本的输入,首先就要转换成适合模型的数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def evaluate(input_sentence):
attention_matrix = np.zeros((max_length_output, max_length_input)) # 定义attention_matrix 保存权重。shape:()
input_sentence = preprocess_sentence(input_sentence) # 输入的句子进行预处理。就是分割标点符号/

inputs = [input_tokenizer.word_index[token] for token in input_sentence.split(' ')] # text--->id 把句子转换成id
inputs = keras.preprocessing.sequence.pad_sequences([inputs], maxlen = max_length_input, padding= 'post') # 把转换成id的向量,进行padding
inputs = tf.convert_to_tensor(inputs) #把向量转换为tensor

results = '' # 定义str, 保存translate的结果

# encoding_hidden = encoder.initialize_hidden_state()

encoding_hidden = tf.zeros((1, units)) #初始化encoding_hidden层

encoding_outputs, encoding_hidden = encoder(inputs, encoding_hidden) # 这一步得到的encoding_hidden就是decoding_hidden 的第一个值
decoding_hidden = encoding_hidden


decoding_input = tf.expand_dims([out_tokenizer.word_index['<start>']], 0) # 找到开始的第一个输入的id
for t in range(max_length_output):
predictions, decoding_hidden, attention_weights = decoder(decoding_input, decoding_hidden, encoding_outputs)
attention_weights = tf.reshape(attention_weights, (-1,))
attention_matrix[t] = attention_weights.numpy()

predicted_id = tf.argmax(predictions[0]).numpy()

results += out_tokenizer.index_word[predicted_id] + ' '

if out_tokenizer.index_word[predicted_id] == '<end>':
return results, input_sentence, attention_matrix

decoding_input = tf.expand_dims([predicted_id], 0)
return results, input_sentence, attention_matrix

def plot_attention(attention_matrix, input_sentence, predicted_sentence):
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(1, 1, 1)

ax.matshow(attention_matrix, cmap='viridis')

font_dict = {'fontsize': 14}

ax.set_xticklabels([''] + input_sentence,
fontdict = font_dict, rotation = 90)
ax.sey_yticklables([''] + predicted_sentence,
fontdict = font_dict,)
plt.show()

def translate(input_sentence):
results, input_sentence, attention_matrix = evaluate(input_sentence)

print("Input: %s" % (input_sentence))
print("Predicted translation: %s" % (results))

attention_matrix = attention_matrix[:len(results.split(' ')),
:len(input_sentence.split(' '))]
plot_attention(attention_matrix, input_sentence.split(' '), results.split(' '))

BahdanauAttention

发表于 2019-08-14
字数统计: 186 | 阅读时长 ≈ 1

2015年提出的BahdanauAttention原文:
https://arxiv.org/pdf/1409.0473.pdf

0814 记录

注意力机制

Encoder会通过RNN将最后一个step的隐藏状态向量c作为输出,Deocder利用向量c进行翻译。这样做有一个缺点,翻译时过分依赖于这个将整个sentence压缩成固定输入的向量。输入的sentence有可能包含上百个单词,这么做不可避免会造成信息的丢失,翻译结果也无法准确了

注意力机制的引入就是为了解决此问题,注意力机制使得机器翻译中利用原始的sentence信息,减少信息损失。

损失函数
预测哪个单词是正确的,是一个分类问题。

model搭建

发表于 2019-08-13
字数统计: 622 | 阅读时长 ≈ 2

python 构造函数

super()

super()是为了调用父类函数

https://www.runoob.com/python3/python3-class.html

encoder构建

定义超参的概念
embedding_units = 256 每个word转成embedding是多少
units = 1024 循环神经网络的个数 encode 和decode的units数量是一样的
encoding_units 在 encode中lstm 的size是多大

hidden 是初始化的隐藏层状态

keras.layers.GRU(units, activation=’tanh’, recurrent_activation=’hard_sigmoid’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, implementation=1, return_sequences=False, return_state=False, go_backwards=False, stateful=False, unroll=False, reset_after=False)

units: 正整数,输出空间的维度。

recurrent_initializer: recurrent_kernel 权值矩阵 的初始化器,用于循环层状态的线性转换 (详见 initializers)。

return_sequences: 布尔值。是返回输出序列中的最后一个输出,还是全部序列。

return_state: 布尔值。除了输出之外是否返回最后一个状态。

https://keras.io/zh/layers/recurrent/

Writing your own Keras layers

https://keras.io/layers/writing-your-own-keras-layers/

glorot_uniform

https://keras.io/zh/initializers/

keras.initializers.glorot_uniform(seed=None)
Glorot 均匀分布初始化器,也称为 Xavier 均匀分布初始化器。

它从 [-limit,limit] 中的均匀分布中抽取样本, 其中 limit 是 sqrt(6 / (fan_in + fan_out)), fan_in 是权值张量中的输入单位的数量, fan_out 是权值张量中的输出单位的数量。

参数
seed: 一个 Python 整数。作为随机发生器的种子。

返回
一个初始化器。

参考文献:http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Encoder (keras.Model):
def __init__(self, vocab_size, embedding_units, encoding_units, batch_size):
super(Encoder, self).__init__()
self.batch_size = batch_size
self.encoding_units = encoding_units
self.embedding = keras.layers.Embedding(vocab_size,embedding_units)
self.gru = keras.layers.GRU(self.encoding_units,return_sequences=True,return_state=True,
recurrent_initializer='glorot_uniform')
def call(self, x, hidden):
x = self.embedding(x)
output, state = self.gru(x, initial_state=hidden) ## 这里的self.gru() 传递的两个参数是什么意思呢?在构造函数里面并没有使用这两个参数, 但是在api里 可以找到这个参数。
return output, state
def initialize_hidden_state(self):
return tf.zeros((self.batch_size,self.encoding_units))

encode = Encoder(input_vocab_size, embedding_units, units, batch_size)

sample_hidden = encoder.initialize_hidden_state()

sample_output, sample_hidden = encoder(x, sample_hidden)


## 输入模型的数据特征
[in]
for array in (input_train, input_eval, output_train, output_eval):
print( type(array), array.shape)
[out]
<class 'numpy.ndarray'> (24, 9)
<class 'numpy.ndarray'> (7, 9)
<class 'numpy.ndarray'> (24, 14)
<class 'numpy.ndarray'> (7, 14)

可以这样理解,对于 input_train 来说,有24个样本,每个样本有9个特征。对于这个9。就是每个句子的单词数,但是有的句子单词不够9个,这在预处理数据的时候进行了padding操作。样本数是24,在train_test_split(test_size=0.2)分配的数据量。

python链表推导式

发表于 2019-08-12
字数统计: 613 | 阅读时长 ≈ 2

链表推导式在很多代码里都出现过,但是语法规则不太了解,今天做个记录。

#我感觉链表推导式就是让代码看上去更清爽。。。

a,b for c, d in

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[In]
a = [(1,2),(3,4),(5,6)]
print(type(a))
print(len(a))
[out]
<class 'list'>
3
[In]
def a(a):
return(print(a))
def b(a):
return(print(a))

a(c),b(d) for c,d in a

Python 中形如 xx for xx in yy 的链表推导式

以 a = [0,1,2,3,4,5] 为例

1. 最简单的情况,使用链表推导式时不需要任何判断,即处理的对象内没有任何特殊值需要特别处理的时候

比如:求 a 内每个元素的平方,我们直接写

b = [ x**2 for x in a]
b [0, 1, 4, 9, 16, 25]

2. 当增加限制条件时,就需要进行判断,然后处理,就需要在链表推导式内添加判断条件

比如:取出 a 内 > 0 的元素

c = [ x for x in a if x > 0 ]
c [1, 2, 3, 4, 5]

3. 链表推导式处理处理内容,还有一个作用是定位,这样可以满足我们先定位再处理的需求

比如:我们要知道 a 内偶数元素的位置

a_even_id = [ i for i,x in enumerate(a) if x%2 == 0 ]
a_even_id
[0, 2, 4]

4. 下面进行难度提升,当处理的对象不是纯数字,即不是我们所需要的数据格式或对象时

A0 = [ 0,’ ‘,1,2,4,5,’ ‘,’3’,2]
A是由整数(int)和空格’ ‘, 以及字符串’3’组成的
我们要将空格替换为 0 ,将’3’ 替换为 整形 3
(1).判断是否是整形: type(x) == int
(2).不是整形,则判断是否是空格:x == ‘ ‘,是则替换为 0,
(3).判断是否是数字构成的字符串:x.isdigit(),(isdigit()是字符串方法),是则转化为整形数
(4). 如果是其他,则均替换为 0 ,(这一步必须有,以为要穷尽多有可能,否则会因为条件没有覆盖到而导致无法执行)

A = [ x if type(x)==int else 0 if x == ‘ ‘ else int(x) if x.isdigit() else 0 for x in A0 ]
A [0, 0, 1, 2, 4, 5, 0, 3, 2]

5. 如果只需要处理 A0 内的整形数据,而舍弃其他的数据,那么我们不必像4中描述的那么复杂,只需要:

A_int = [x for x in A0 if type(x)==int ]
A_int
[0, 1, 2, 4, 5, 2]

Generate_x_y_data_v1()函数理解

发表于 2019-08-11
字数统计: 362 | 阅读时长 ≈ 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def generate_x_y_data_v1(isTrain, batch_size):
# """
# 练习数据1。
#      返回:元组(X,Y)
#          X是从0.0 * pi到1.5 * pi的正弦和余弦
#          Y是从1.5 * pi到3.0 * pi的正弦和余弦
#      因此,Y跟随X.还有一个通常应用于X和Y的随机偏移。

#      返回的数组具有以下形状:(seq_length,batch_size,output_dim)
# 因此:(10,batch_size,2)
#      对于本练习,让我们忽略“isTrain”
#      论证和测试相同的数据。
# """
seq_length = 3
batch_size = 3

batch_x = []
batch_y = []
for _ in range(batch_size):
rand = random.random() * 2 * math.pi

sig1 = np.sin(np.linspace(0.0 * math.pi + rand,
3.0 * math.pi + rand, seq_length * 2))
print(_)
print(sig1)
sig2 = np.cos(np.linspace(0.0 * math.pi + rand,
3.0 * math.pi + rand, seq_length * 2))
x1 = sig1[:seq_length]
y1 = sig1[seq_length:]
x2 = sig2[:seq_length]
y2 = sig2[seq_length:]

x_ = np.array([x1, x2])
y_ = np.array([y1, y2])
x_, y_ = x_.T, y_.T

batch_x.append(x_)
batch_y.append(y_)

batch_x = np.array(batch_x)
batch_y = np.array(batch_y)
# shape: (batch_size, seq_length, output_dim)

batch_x = np.array(batch_x).transpose((1, 0, 2))
batch_y = np.array(batch_y).transpose((1, 0, 2))
# shape: (seq_length, batch_size, output_dim)

return batch_x, batch_y

sig1 是ndarray类型,长度为seq_length*2 , 主要np.linspace()函数。

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)

sig2 和sig1 一样的思路
x1 y1 是对sig1的截取,分别取前半段和后半段
x2 y2 是对sig2的截取,分别取前半段和后半段

batch_x 就是x1 x2 形成的矩阵。
batch_y 就是y1 y2 形成的矩阵。

batch_x.shape = (seq_length, batch_size,2)

有seq_length个样本,每个样本的维度 (batch_size,2)

span-english

  1. preprocessing data
  2. build model
  3. 1 encoder
  4. 2 Attention
  5. 3 decoder
  6. evaluation
  7. 1 given sentence, return translated results
  8. 2 visualize results(attention)
1…171819…25
Square Face

Square Face

少不吃苦是废人,老不吃苦是贵人

121 日志
3 分类
32 标签
GitHub E-Mail YouTube Instagram
© 2020 Square Face | Site words total count: 45.5k
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4