英文可以以word形式编码。但是这种编码方式的问题在于在测试或者实际应用的时候出现 out-of-vocabulary(OOV)的问题,所以我们可以编码character。
以句子“these models make use of neural networks”为例。
我们的字典为
我们对这个文件处理生成字典
character_to_id = {}
with open('C:\\Users\\15226\\Desktop\\character.txt', 'r', encoding='utf-8') as f:
for num, line in enumerate(f.readlines()):
character_to_id[line.replace('\n', '')] = num
句子字符向量化代码
def character_encode(sentence):
vector = np.zeros([sequence, max_character])
for n, s in enumerate(sentence.split()):
for nn, c in enumerate(s):
vector[n][nn] = character_to_id[c]
return vector
这里面是直接对句子进行character向量化,也可以先对单词进行character向量化,再对句子进行向量化
如果是一个batch的句子,我们向量化后会得到[batch_size,seq_len,max_char]的一个矩阵,经过embedding后,会得到一个[batch_size,seq_len,max_char,dim]的矩阵,再经过CNN处理,就可以将矩阵处理成rank=3的。
def make_conv(inp):
convolutions = []
for i, (width, num) in enumerate(filters):
# He initialization for ReLU activation
# with char embeddings init between -1 and 1
# w_init = tf.random_normal_initializer(
# mean=0.0,
# stddev=np.sqrt(2.0 / (width * char_embed_dim))
# )
# Kim et al 2015, +/- 0.05
w_init = tf.random_uniform(
minval=-0.05, maxval=0.05)
w = tf.get_variable(
[1, width, char_embed_dim, num],
initializer=w_init,
dtype=tf.float32)
b = tf.get_variable(
"b_cnn_%s" % i, [num], dtype=tf.float32,
initializer=tf.constant_initializer(0.0))
conv = tf.nn.conv2d( # (batch_size, unroll_steps,max_chars - width + 1,num) 在词上面卷
inp, w,
strides=[1, 1, 1, 1],
padding="VALID") + b
# now max pool
# (batch_size, unroll_steps,1,num),因为是多个卷积核,池化过后跟卷积核的宽度就没有关系了
# 因为是char编码,这样就可以看到多个char,就相当于看到一个词的一部分或者多部分
conv = tf.nn.max_pool(
conv, [1, 1, max_character - width + 1, 1],
[1, 1, 1, 1], 'VALID') #
# activation
conv = tf.nn.relu(conv)
conv = tf.squeeze(conv, squeeze_dims=[2]) # (batch_size, unroll_steps,num)
convolutions.append(conv)
return tf.concat(convolutions, 2)