问题描述:样本为所有恐龙名字,为了构建字符级语言模型来生成新的名称,你的模型将学习不同的名称模式,并随机生成新的名字。

在这里你将学习到:

  • 如何存储文本数据以便使用rnn进行处理。
  • 如何合成数据,通过每次采样预测,并将其传递给下一个rnn单元。
  • 如何构建字符级文本生成循环神经网络。
  • 为什么梯度修剪很重要?
  1. import numpy as np
  2. import random
  3. import time
  4. import cllm_utils

1 - 问题描述

1.1 - 数据集与预处理

  1. # 获取名称
  2. data = open("dinos.txt", "r").read()
  3.  
  4. # 转化为小写字符
  5. data = data.lower()
  6.  
  7. # 转化为无序且不重复的元素列表
  8. chars = list(set(data))
  9.  
  10. # 获取大小信息
  11. data_size, vocab_size = len(data), len(chars)
  12.  
  13. print(chars)
  14. print("共计有%d个字符,唯一字符有%d个"%(data_size,vocab_size))
  1. data='Aachenosaurus\nAardonyx\nAbdallahsaurus\...'
  1. chars=['o', 'm', 'k', 'v', 'w', 'b', 'j', 'd', 'x', 'a', 'h', 'i',
    'e', 'l', 's', 't', 'n', 'z', 'p', 'y', 'g', 'f', '\n', 'q',
    'r', 'u', 'c']
    共计有19909个字符,唯一字符有27
  1. char_to_ix = {ch:i for i,ch in enumerate(sorted(chars))}
  2. ix_to_char = {i:ch for i,ch in enumerate(sorted(chars))}
  3.  
  4. print(char_to_ix)
  5. print(ix_to_char)
  1. {'\n': 0, 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6,
    'g': 7, 'h': 8, 'i': 9, 'j': 10, 'k': 11, 'l': 12, 'm': 13,
    'n': 14, 'o': 15, 'p': 16, 'q': 17, 'r': 18, 's': 19, 't': 20,
    'u': 21, 'v': 22, 'w': 23, 'x': 24, 'y': 25, 'z': 26}
  2. {0: '\n', 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f',
    7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm',
    14: 'n', 15: 'o', 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't',
    21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z'}

1.2 - 模型回顾

模型的结构如下:

  • 初始化参数
  • 循环:
    • 前向传播计算损失
    • 反向传播计算关于损失的梯度
    • 修剪梯度以免梯度爆炸
    • 用梯度下降更新规则更新参数。
  • 返回学习后了的参数

2 - 构建模型中的模块

在这部分,我们将来构建整个模型中的两个重要的模块:

  • 梯度修剪:避免梯度爆炸
  • 取样:一种用来产生字符的技术

2.1 梯度修剪

     在这里,我们将实现在优化循环中调用的clip函数.回想一下,整个循环结构通常包括前向传播、成本计算、反向传播和参数更新。

在更新参数之前,我们将在需要时执行梯度修剪,以确保我们的梯度不是“爆炸”的.

    接下来我们将实现一个修剪函数,该函数输入一个梯度字典输出一个已经修剪过了的梯度.有很多的方法来修剪梯度,我们在这里

使用一个比较简单的方法.梯度向量的每一个元素都被限制在[−N,N]的范围,通俗的说,有一个maxValue(比如10),

如果梯度的任何值大于10,那么它将被设置为10,如果梯度的任何值小于-10,那么它将被设置为-10,如果它在-10与10之间,那么它将不变。

  1. def clip(gradients, maxValue):
  2. """
  3. 使用maxValue来修剪梯度
  4.  
  5. 参数:
  6. gradients -- 字典类型,包含了以下参数:"dWaa", "dWax", "dWya", "db", "dby"
  7. maxValue -- 阈值,把梯度值限制在[-maxValue, maxValue]内
  8.  
  9. 返回:
  10. gradients -- 修剪后的梯度
  11. """
  12. # 获取参数
  13. dWaa, dWax, dWya, db, dby = gradients['dWaa'], gradients['dWax'], gradients['dWya'], gradients['db'], gradients['dby']
  14.  
  15. # 梯度修剪
  16. for gradient in [dWaa, dWax, dWya, db, dby]:
  17. np.clip(gradient, -maxValue, maxValue, out=gradient)
  18.  
  19. gradients = {"dWaa": dWaa, "dWax": dWax, "dWya": dWya, "db": db, "dby": dby}
  20.  
  21. return gradients

函数接受最大阈值,并返回修剪后的梯度

2.2 - 采样

  1. 1 def sample(parameters, char_to_is, seed):
  2. 2 """
  3. 3 根据RNN输出的概率分布序列对字符序列进行采样
  4. 4
  5. 5 参数:
  6. 6 parameters -- 包含了Waa, Wax, Wya, by, b的字典
  7. 7 char_to_ix -- 字符映射到索引的字典
  8. 8 seed -- 随机种子
  9. 9
  10. 10 返回:
  11. 11 indices -- 包含采样字符索引的长度为n的列表。
  12. 12 """
  13. 13
  14. 14 # 从parameters 中获取参数
  15. 15 Waa, Wax, Wya, by, b = parameters['Waa'], parameters['Wax'], parameters['Wya'],
    parameters['by'], parameters['b']
  16. 16 vocab_size = by.shape[0]
  17. 17 n_a = Waa.shape[1]
  18. 18
  19. 19 # 步骤1
  20. 20 ## 创建独热向量x
  21. 21 x = np.zeros((vocab_size,1))
  22. 22
  23. 23 ## 使用0初始化a_prev
  24. 24 a_prev = np.zeros((n_a,1))
  25. 25
  26. 26 # 创建索引的空列表,这是包含要生成的字符的索引的列表。
  27. 27 indices = []
  28. 28
  29. 29 # IDX是检测换行符的标志,我们将其初始化为-1。
  30. 30 idx = -1
  31. 31
  32. 32 # 循环遍历时间步骤t。在每个时间步中,从概率分布中抽取一个字符,
  33. 33 # 并将其索引附加到“indices”上,如果我们达到50个字符,
  34. 34 #(我们应该不太可能有一个训练好的模型),我们将停止循环,这有助于调试并防止进入无限循环
  35. 35 counter = 0
  36. 36 newline_character = char_to_ix["\n"]
  37. 37
  38. 38 while (idx != newline_character and counter < 50):
  39. 39 # 步骤2:使用公式1、2、3进行前向传播
  40. 40 a = np.tanh(np.dot(Wax, x) + np.dot(Waa, a_prev) + b)
  41. 41 z = np.dot(Wya, a) + by
  42. 42 y = cllm_utils.softmax(z)
  43. 43
  44. 44 # 设定随机种子
  45. 45 np.random.seed(counter + seed)
  46. 46
  47. 47 # 步骤3:从概率分布y中抽取词汇表中字符的索引
  48. 48 idx = np.random.choice(list(range(vocab_size)), p=y.ravel())
  49. 49
  50. 50 # 添加到索引中
  51. 51 indices.append(idx)
  52. 52
  53. 53 # 步骤4:将输入字符重写为与采样索引对应的字符。
  54. 54 x = np.zeros((vocab_size,1))
  55. 55 x[idx] = 1
  56. 56
  57. 57 # 更新a_prev为a
  58. 58 a_prev = a
  59. 59
  60. 60 # 累加器
  61. 61 seed += 1
  62. 62 counter +=1
  63. 63
  64. 64 if(counter == 50):
  65. 65 indices.append(char_to_ix["\n"])
  66. 66
  67. 67 return indices

3 - 构建语言模型

3.1 - 梯度下降

 在这里,我们将实现一个执行随机梯度下降的一个步骤的函数(带有梯度修剪)。我们将一次训练一个样本,所以优化算法将是随机梯度下降,这里是RNN的一个通用的优化循环的步骤:

  • 前向传播计算损失
  • 反向传播计算关于参数的梯度损失
  • 修剪梯度
  • 使用梯度下降更新参数

 我们来实现这一优化过程(单步随机梯度下降),这里我们提供了一些函数:

  1. # 示例,可参照上一篇博客RNN的前向后向传播。
  2. def rnn_forward(X, Y, a_prev, parameters):
  3. """
  4. 通过RNN进行前向传播,计算交叉熵损失。
  5.  
  6. 它返回损失的值以及存储在反向传播中使用的“缓存”值。
  7. """
  8. ....
  9. return loss, cache
  10.  
  11. def rnn_backward(X, Y, parameters, cache):
  12. """
  13. 通过时间进行反向传播,计算相对于参数的梯度损失。它还返回所有隐藏的状态
  14. """
  15. ...
  16. return gradients, a
  17.  
  18. def update_parameters(parameters, gradients, learning_rate):
  19. """
  20. Updates parameters using the Gradient Descent Update Rule
  21. """
  22. ...
  23. return parameters
  1. def optimize(X, Y, a_prev, parameters, learning_rate = 0.01):
  2. """
  3. 执行训练模型的单步优化。
  4.  
  5. 参数:
  6. X -- 整数列表,其中每个整数映射到词汇表中的字符。
  7. Y -- 整数列表,与X完全相同,但向左移动了一个索引。
  8. a_prev -- 上一个隐藏状态
  9. parameters -- 字典,包含了以下参数:
  10. Wax -- 权重矩阵乘以输入,维度为(n_a, n_x)
  11. Waa -- 权重矩阵乘以隐藏状态,维度为(n_a, n_a)
  12. Wya -- 隐藏状态与输出相关的权重矩阵,维度为(n_y, n_a)
  13. b -- 偏置,维度为(n_a, 1)
  14. by -- 隐藏状态与输出相关的权重偏置,维度为(n_y, 1)
  15. learning_rate -- 模型学习的速率
  16.  
  17. 返回:
  18. loss -- 损失函数的值(交叉熵损失)
  19. gradients -- 字典,包含了以下参数:
  20. dWax -- 输入到隐藏的权值的梯度,维度为(n_a, n_x)
  21. dWaa -- 隐藏到隐藏的权值的梯度,维度为(n_a, n_a)
  22. dWya -- 隐藏到输出的权值的梯度,维度为(n_y, n_a)
  23. db -- 偏置的梯度,维度为(n_a, 1)
  24. dby -- 输出偏置向量的梯度,维度为(n_y, 1)
  25. a[len(X)-1] -- 最后的隐藏状态,维度为(n_a, 1)
  26. """
  27.  
  28. # 前向传播
  29. loss, cache = cllm_utils.rnn_forward(X, Y, a_prev, parameters)
  30.  
  31. # 反向传播
  32. gradients, a = cllm_utils.rnn_backward(X, Y, parameters, cache)
  33.  
  34. # 梯度修剪,[-5 , 5]
  35. gradients = clip(gradients,5)
  36.  
  37. # 更新参数
  38. parameters = cllm_utils.update_parameters(parameters,gradients,learning_rate)
  39.  
  40. return loss, gradients, a[len(X)-1]

给定恐龙名称的数据集,我们使用数据集的每一行(一个名称)作为一个训练样本。每100步随机梯度下降,你将抽样10个随机选择的名字,看看算法是怎么做的。

3.2 - 训练模型

记住要打乱数据集,以便随机梯度下降以随机顺序访问样本。当examples[index]包含一个恐龙名称(String)时,为了创建一个样本(X,Y),你可以使用这个:

  1. index = j % len(examples)
  2. X = [None] + [char_to_ix[ch] for ch in examples[index]]
  3. Y = X[1:] + [char_to_ix["\n"]]
  1. def model(data, ix_to_char, char_to_ix, num_iterations=3500,
  2. n_a=50, dino_names=7,vocab_size=27):
  3. """
  4. 训练模型并生成恐龙名字
  5.  
  6. 参数:
  7. data -- 语料库
  8. ix_to_char -- 索引映射字符字典
  9. char_to_ix -- 字符映射索引字典
  10. num_iterations -- 迭代次数
  11. n_a -- RNN单元数量
  12. dino_names -- 每次迭代中采样的数量
  13. vocab_size -- 在文本中的唯一字符的数量
  14.  
  15. 返回:
  16. parameters -- 学习后了的参数
  17. """
  18.  
  19. # 从vocab_size中获取n_x、n_y
  20. n_x, n_y = vocab_size, vocab_size
  21.  
  22. # 初始化参数
  23. parameters = cllm_utils.initialize_parameters(n_a, n_x, n_y)
  24.  
  25. # 初始化损失
  26. loss = cllm_utils.get_initial_loss(vocab_size, dino_names)
  27.  
  28. # 构建恐龙名称列表
  29. with open("dinos.txt") as f:
  30. examples = f.readlines()
  31. examples = [x.lower().strip() for x in examples]
  32.  
  33. # 打乱全部的恐龙名称
  34. np.random.seed(0)
  35. np.random.shuffle(examples)
  36.  
  37. # 初始化LSTM隐藏状态
  38. a_prev = np.zeros((n_a,1))
  39.  
  40. # 循环
  41. for j in range(num_iterations):
  42. # 定义一个训练样本
  43. index = j % len(examples)
  44. X = [None] + [char_to_ix[ch] for ch in examples[index]]
  45. Y = X[1:] + [char_to_ix["\n"]]
  46.  
  47. # 执行单步优化:前向传播 -> 反向传播 -> 梯度修剪 -> 更新参数
  48. # 选择学习率为0.01
  49. curr_loss, gradients, a_prev = optimize(X, Y, a_prev, parameters)
  50.  
  51. # 使用延迟来保持损失平滑,这是为了加速训练。
  52. loss = cllm_utils.smooth(loss, curr_loss)
  53.  
  54. # 每2000次迭代,通过sample()生成“\n”字符,检查模型是否学习正确
  55. if j % 2000 == 0:
  56. print("第" + str(j+1) + "次迭代,损失值为:" + str(loss))
  57.  
  58. seed = 0
  59. for name in range(dino_names):
  60. # 采样
  61. sampled_indices = sample(parameters, char_to_ix, seed)
  62. cllm_utils.print_sample(sampled_indices, ix_to_char)
  63.  
  64. # 为了得到相同的效果,随机种子+1
  65. seed += 1
  66.  
  67. print("\n")
  68. return parameters

比如说某恐龙名字叫 zzh

那么X = ['0','z','z','h']

Y = ['z','z','h','\n']

需要注意的是我们使用了

index= j % len(examples),

其中= 1....num_iterations,

为了确保examples[index]总是有效的

(index小于len(examples)),

rnn_forward()会将X的第一个值None解释为

x<0>=0向量.

此外,为了确保Y等于X,会向左移动一步,

并添加一个附加的“\n”以表示恐龙名称的结束。

  1. #开始时间
  2. start_time = time.clock()
  3.  
  4. #开始训练
  5. parameters = model(data, ix_to_char, char_to_ix, num_iterations=3500)
  6.  
  7. #结束时间
  8. end_time = time.clock()
  9.  
  10. #计算时差
  11. minium = end_time - start_time
  12.  
  13. print("执行了:" + str(int(minium / 60)) + "分" + str(int(minium%60)) + "秒")

结果如下:

第1次迭代,

损失值为:23.0873360855
Nkzxwtdmfqoeyhsqwasjkjvu
Kneb
Kzxwtdmfqoeyhsqwasjkjvu
Neb
Zxwtdmfqoeyhsqwasjkjvu
Eb
Xwtdmfqoeyhsqwasjkjvu

第2001次迭代,

损失值为:27.8841604914
Liusskeomnolxeros
Hmdaairus
Hytroligoraurus
Lecalosapaus
Xusicikoraurus
Abalpsamantisaurus
Tpraneronxeros

以上是自己定义参数来实现字符语言模型,下面用keras实现。

  1. #获取恐龙的名称
  2. data = open('dinos.txt','r').read()
  3. data = data.lower()
  4.  
  5. chars = list(set(data))
  6.  
  7. data_size,vocab_size = len(data),len(chars)
  8.  
  9. print(chars)
  10. print("共计有%d个字符,唯一字符有%d个"%(data_size,vocab_size))

  1. ['r', 'p', 'j', 'i', 't', 'z', 'q', 'o', 'd',
    'x', 's', 'v', 'e', 'l', 'g', 'k', 'n', 'm',
    'c', 'b', 'f', 'y', 'w', 'u', 'h', 'a', '\n']
  2. 共计有19909个字符,唯一字符有27

  1. kl_name = open('dinos.txt','r').read().lower()
  2. # kl_name =kl_name.lower().split('\n')
  3. # len(kl_name.split('\n'))
  4. print(kl_name[:50])
 

  1. char_to_ix = {ch:i for i,ch in enumerate(sorted(chars))}
  2. ix_to_char = {i:ch for i,ch in enumerate(sorted(chars))}
  3.  
  4. print(char_to_ix)
  5. print(ix_to_char)

  1. {'\n': 0, 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5,
    'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10, 'k': 11,
    'l': 12, 'm': 13, 'n': 14, 'o': 15, 'p': 16,
    'q': 17, 'r': 18, 's': 19, 't': 20, 'u': 21,
    'v': 22, 'w': 23, 'x': 24, 'y': 25, 'z': 26}
  2. {0: '\n', 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e',
    6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k',
    12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p',
    17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u',
    22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z'}

  1. #将字符序列向量化
  2. max_len = 8
  3.  
  4. names = []
  5. next_chars = []
  6.  
  7. for i in range(0,len(kl_name)-maxlen):
  8. names.append(kl_name[i:i+max_len])
  9. next_chars.append(kl_name[i+max_len])
  10. #每句话之后的下一个字符,相当于是label
  11.  
  12. x = np.zeros((len(names),maxlen,len(char_to_ix)))
  13. y = np.zeros((len(names),len(char_to_ix)))
  14.  
  15. for i,name in enumerate(names):
  16. for j,char in enumerate(name):
  17. x[i,j,char_to_ix[char]] = 1
  18. y[i,char_to_ix[next_chars[i]]]=1
  19.  
  20. print('x.shape',x.shape)
  21. print('y.shape',y.shape)
  22. print(names[:4])
  23. print(next_chars[:4])
  1. x.shape (19879, 30, 27)
  2. y.shape (19879, 27)
  3. ['aachenos', 'achenosa', 'chenosau', 'henosaur']
  4. ['a', 'u', 'r', 'u']

x是从原字符串中,每max_len个字符生成的样本

y是每个样本的后一个字符

比如说原字符串为=''abcdefghijklmn',max_len=8

x = ['abcdefgh','bcdefghi','cdefghij',...]

y = ['i','j','k',...]

  1. #构建用于预测下一个字符的单层LSTM模型
  2. from keras.layers import SimpleRNN,Dense
  3. from keras.models import Sequential
  4. model = Sequential()
  5. model.add(SimpleRNN(128,input_shape=(maxlen,len(char_to_ix))))
  6. model.add(Dense(len(char_to_ix),activation='softmax'))
  7. model.summary()
 

注意:输入model里面的input的size是不包括所有样本的,

也就是说只有一个样本的大小(时间步,oe-hot的长度),

在fit的时候x是包含所有样本的x.shape(样本个数,样本的

长度,每个字符one-hot的长度)

  1. #模型编译配置
  2. import keras
  3. optimizers = keras.optimizers.RMSprop(lr=0.01)
  4. model.compile(optimizer='rmsprop',
  5. loss = 'categorical_crossentropy',
  6. metrics = ['acc'])
  7.  
  8. #目标是经过one-hot编码的,所以训练模型需要使用categorical_crossentropy作为损失
 
   

  1. #给定模型预测、采样下一个字符的函数
  2. def sample(preds,temperature=0.1):
  3. preds = np.asarray(preds).astype('float64')
  4. preds = np.log(preds) / temperature
  5. exp_preds = np.exp(preds)
  6. preds = exp_preds / np.sum(exp_preds)
  7. probas = np.random.multinomial(1,preds,1)
  8. return np.argmax(probas)

 每次predict之后,得到一个softmax之后的向量,该选取

哪个单词作为label呢?

(1)贪婪采样:每次都选可能性最大的下一个字符,但这种方法会

得到重复的、可预测的字符串

(2)随机采样:控制随机性的大小-->softmax温度

更高的温度得到的熵是更大的采样分布,会生成更加出人意料、

更加无结构的生成数据;更低的温度对应更小的随机性,以及更

加可预测的生成数据。

  1. import sys
  2. import numpy as np
  3. #文本生成循环
  4. epochs = 6
  5. for epoch in range(1,epochs):#每次循环生成10个字符(只保留最新的10个),循环6
  6. print('epoch',epoch)
  7. model.fit(x,y,batch_size=128,epochs=1)
  8.  
  9. #随机选取一个文本片段
  10. start_index = np.random.randint(0,len(names)-1)
  11. generated_text = names[start_index]
  12. print('--- Generating with seed:"' + generated_text[1:] + '"')
  13. for temperature in [0.2,0.5,1.0,1.2]:
  14. print("第"+str(epoch)+"次,temperature="+str(temperature)+
    "生成的文本为"+generated_text)
  15.  
  16. #生成10个字符
  17. for i in range(10):
  18. sampled = np.zeros((1,maxlen,len(char_to_ix)))
  19. for j,char in enumerate(generated_text):
  20. sampled[0,j,char_to_ix[char]] = 1
              #将生成的10个字符转成one-hot的形式
  21. preds = model.predict(sampled,verbose=0)[0]
            #预测的结果 predict的shape为(1,27)
  22.  
  23. next_index = sample(preds=preds,temperature=temperature)
            #采样
  24. next_char = ix_to_char[next_index]
  25.  
  26. generated_text += next_char
  27. generated_text = generated_text[1:]
           #更新generated_text每轮只留最新的后0个字符

  1. epoch 1
  2. Epoch 1/1
  3. 19879/19879 [==============================] - 5s
    265us/step - loss: 1.3650 - acc: 0.5864
  4. --- Generating with seed:"amosaur"
  5. 1次,temperature=0.2生成的文本为hamosaur
  6. (1, 27)
  7. 1次,temperature=0.5生成的文本为hamosaur
  8. (1, 27)
  9. 1次,temperature=1.0生成的文本为hamosaur
  10. (1, 27)
  11. 1次,temperature=1.2生成的文本为hamosaur
  12. (1, 27)
  13. epoch 2
  14. Epoch 1/1
  15. 19879/19879 [==============================] - 5s
    273us/step - loss: 1.3569 - acc: 0.5858
  16. --- Generating with seed:"nimanta"
  17. 2次,temperature=0.2生成的文本为animanta
  18. (1, 27)
  19. 2次,temperature=0.5生成的文本为animanta
  20. (1, 27)
  21. 2次,temperature=1.0生成的文本为animanta
  22. (1, 27)
  23. 2次,temperature=1.2生成的文本为animanta
  24. (1, 27)

参考文献:

1.【用Keras开发字符级神经网络语言模型】

2.【对于LSTM输入层、隐含层及输出层参数的个人理解】

3.【keras的主要模块介绍】

RNN实现字符级语言模型 - 恐龙岛(自己写RNN前向后向版本+keras版本)的更多相关文章

  1. tf.contrib.rnn.core_rnn_cell.BasicLSTMCell should be replaced by tf.contrib.rnn.BasicLSTMCell.

    For Tensorflow 1.2 and Keras 2.0, the line tf.contrib.rnn.core_rnn_cell.BasicLSTMCell should be repl ...

  2. 自己动手写RNN

    说的再好,也不如实际行动,今天手写了一个RNN,没有使用Numpy库,自己写的矩阵运算方法,由于这也只是个学习用的demo,所以矩阵运算那一部分写的比较丑陋,见笑了. import com.mylea ...

  3. 代码实现:获取一个文本上每个字符出现的次数,将结果写在times.txt上

    package com.loaderman.test; import java.io.BufferedReader; import java.io.BufferedWriter; import jav ...

  4. 字符输出流_Writer类&FileWriter类介绍和字符输出流的基本使用_写出单个字符到文件

    java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类 共性的成员方法: - void write(int c) 写入单个字符 - void write(char[] ...

  5. 字符输出流_Writer类&FileWrite类介绍和字符输出流的基本使用_写出单个字符到文件

    字符输出流_Writer类&FileWrite类介绍 java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类 共性抽象方法: void write(int c) ...

  6. Pytorch系列教程-使用字符级RNN生成姓名

    前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutor ...

  7. Pytorch系列教程-使用字符级RNN对姓名进行分类

    前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_classification_t ...

  8. RNN 通过字符语言模型 理解BPTT

    链接:https://github.com/karpathy/char-rnn http://karpathy.github.io/2015/05/21/rnn-effectiveness/ http ...

  9. 学习笔记TF021:预测编码、字符级语言建模、ArXiv摘要

    序列标注(sequence labelling),输入序列每一帧预测一个类别.OCR(Optical Character Recognition 光学字符识别). MIT口语系统研究组Rob Kass ...

随机推荐

  1. 【大数据系列】hadoop单机模式安装

    一.添加用户和用户组 adduser hadoop 将hadoop用户添加进sudo用户组 sudo usermod -G sudo hadoop 或者 visudo 二.安装jdk 具体操作参考:c ...

  2. 跟我一起写Makefile:使用函数

    跟我一起写Makefile:使用函数 两个排版不一样 书籍下载 书籍下载

  3. Java初学者都必须理解的六大问题 (整理自网络)

    问题一:我声明了什么! 1. String s = "Helloworld!"; 许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello ...

  4. sencha touch 在线实战培训 第一期 第四节

    2014.1.4晚上8点开的课 第一节收费课程,还是有几位同学付费了,这些课程也录像了的,以后也会持续销售. 本期培训一共八节,前三堂免费,后面的课程需要付费才可以观看. 本节内容:          ...

  5. Linux系统更改网卡名称

    自己装了一台机器,有两张网卡,一个是主板上自带的,还有一个是后来自己添加的.装完系统后,系统默认主板上的网卡为eth1,而自己添加的网卡是eth0,感觉不爽,所以想办法使用udev使系统将主板上的网卡 ...

  6. 实战BRTSvc一款我见过的最嚣张的挖矿软件

    第一步:发现告警 Suricata发现特征字符串jsonrpc,这个是匹配挖矿木马的一个重要特征.于是开始分析告警信息: 告警中可以提取出的有效信息如下: 目标IP:149.28.199.108 目标 ...

  7. EJBCA的安装(基于Ubuntu 16.04 LTS + wildfly8 + ejbca6.3.11 + jdk7)

    前一段时间折腾了一下PKI,用EJBCA在研究院内网搭建了一个CA,目前是提供给手机端(安卓和IOS)来和服务器端(nginx + Java应用)做安全连接的(客户端和服务器端双向认证) 由于EJBC ...

  8. Dokcer制作nginx镜像,提交镜像至仓库

    生成Dockerfile FROM docker.io/hagaico/centos-base-6.5:latest MAINTAINER yatho yatho@163.com ENV DEBIAN ...

  9. Office word 2007不能另存为pdf格式的解决方法

    我们在使用Office word 2007时,经常会使用到另存为 PDF 或 XPS(P),遗憾的是,很多人都找不到这个选项, 或者在安装word的时候,并没有安装该加载项,需要你在后期安装,我们来怎 ...

  10. java读取写入oracle的blob字段工具类

    import com.hzunitech.fxgk.sys.model.UtFileData;import com.jfinal.kit.PathKit;import com.jfinal.plugi ...