Python使用循环神经网络解决文本分类问题的方法详解

本文实例讲述了Python使用循环神经网络解决文本分类问题的方法。分享给大家供大家参考,具体如下:

1、概念

1.1、循环神经网络

循环神经网络(Recurrent Neural Network, RNN)是一类以序列数据为输入,在序列的演进方向进行递归且所有节点(循环单元)按链式连接的递归神经网络。

卷积网络的输入只有输入数据X,而循环神经网络除了输入数据X之外,每一步的输出会作为下一步的输入,如此循环,并且每一次采用相同的激活函数和参数。在每次循环中,x0乘以系数U得到s0,再经过系数W输入到下一次,以此循环构成循环神经网络的正向传播。

          

在反向传播中要求损失函数E对参数W的导数,通过链式求导法则可以得到右下的公式

  

循环神经网络与卷积神经网络作比较,卷积神经网络是一个输出经过网络产生一个输出。而循环神经网络可以实现一个输入多个输出(生成图片描述)、多个输入一个输出(文本分类)、多输入多输出(机器翻译、视频解说)。

RNN使用的是tan激活函数,输出在-1到1之间,容易梯度消失。距离输出较远的步骤对于梯度贡献很小。

将底层的输出作为高层的输入就构成了多层的RNN网络,而且高层之间也可以进行传递,并且可以采用残差连接防止过拟合。

1.2、长短期记忆网络

RNN的每次传播之间只有一个参数W,用这一个参数很难描述大量的、复杂的信息需求,为了解决这个问题引入了长短期记忆网络(Long Short Term Memory,LSTM)。这个网络可以进行选择性机制,选择性的输入、输出需要使用的信息以及选择性地遗忘不需要的信息。选择性机制的实现是通过Sigmoid门实现的,sigmoid函数的输出介于0到1之间,0代表遗忘,1代表记忆,0.5代表记忆50%

LSTM网络结构如下图所示,

   

如上右图所示为本轮运算的隐含状态state,当前状态由上一状态和遗忘门结果作点积,再加上传入们结果得到

如下左图所示为遗忘门结构,上一轮的输出ht-1和数据xt在经过遗忘门选择是否遗忘之后,产生遗忘结果ft

如下中图所示为传入门结构,ht-1和xt在经过遗忘门的结果it和tanh的结果Ct作点积运算得到本次运算的输入

如下右图所示为输出门结构,ht-1和xt经过遗忘门的结果ot与当状态作点积产生本次的输出

   

如下实现LSTM网络,首先定义_generate_params函数用于生成每个门所需的参数,调用该函数定义输入门、输出门、遗忘门、和中间状态tanh的参数。每个门的参数都是三个,输入x、h的权重和偏置值。

接着开始进行LSTM的每轮循环计算,输入门计算就是将输入embedded_input矩阵乘以输入门参数x_in,再加上h和对应参数相乘的结果,最后再加上偏置值b_in经过sigmoid便得到输入门结果。

同理进行矩阵相乘加偏置操作得到遗忘门、输出门的结果。中间态tanh与三个门的操作类似,只不过最后经过tanh函数。

将上一个隐含态state乘以遗忘门加上输入门乘以中间态的结果就得到当前的隐含态state

将当前的state经过tanh函数再加上输出门就得到本轮的输出h

经过多轮输入循环得到的就是LSTM网络的最后输出。

# 实现LSTM网络
  # 生成Cell网格所需参数
  def _generate_paramas(x_size, h_size, b_size):
    x_w = tf.get_variable('x_weight', x_size)
    h_w = tf.get_variable('h_weight', h_size)
    bias = tf.get_variable('bias', b_size, initializer=tf.constant_initializer(0.0))
    return x_w, h_w, bias

  scale = 1.0 / math.sqrt(embedding_size + lstm_nodes[-1]) / 3.0
  lstm_init = tf.random_uniform_initializer(-scale, scale)
  with tf.variable_scope('lstm_nn', initializer=lstm_init):
    # 输入门参数
    with tf.variable_scope('input'):
      x_in, h_in, b_in = _generate_paramas(
        x_size=[embedding_size, lstm_nodes[0]],
        h_size=[lstm_nodes[0], lstm_nodes[0]],
        b_size=[1, lstm_nodes[0]]
      )
    # 输出门参数
    with tf.variable_scope('output'):
      x_out, h_out, b_out = _generate_paramas(
        x_size=[embedding_size, lstm_nodes[0]],
        h_size=[lstm_nodes[0], lstm_nodes[0]],
        b_size=[1, lstm_nodes[0]]
      )
    # 遗忘门参数
    with tf.variable_scope('forget'):
      x_f, h_f, b_f = _generate_paramas(
        x_size=[embedding_size, lstm_nodes[0]],
        h_size=[lstm_nodes[0], lstm_nodes[0]],
        b_size=[1, lstm_nodes[0]]
      )
    # 中间状态参数
    with tf.variable_scope('mid_state'):
      x_m, h_m, b_m = _generate_paramas(
        x_size=[embedding_size, lstm_nodes[0]],
        h_size=[lstm_nodes[0], lstm_nodes[0]],
        b_size=[1, lstm_nodes[0]]
      )

    # 两个初始化状态,隐含状态state和初始输入h
    state = tf.Variable(tf.zeros([batch_size, lstm_nodes[0]]), trainable=False)
    h = tf.Variable(tf.zeros([batch_size, lstm_nodes[0]]), trainable=False)
    # 遍历LSTM每轮循环,即每个词的输入过程
    for i in range(max_words):
      # 取出每轮输入,三维数组embedd_inputs的第二维代表训练的轮数
      embedded_input = embedded_inputs[:, i, :]
      # 将取出的结果reshape为二维
      embedded_input = tf.reshape(embedded_input, [batch_size, embedding_size])
      # 遗忘门计算
      forget_gate = tf.sigmoid(tf.matmul(embedded_input, x_f) + tf.matmul(h, h_f) + b_f)
      # 输入门计算
      input_gate = tf.sigmoid(tf.matmul(embedded_input, x_in) + tf.matmul(h, h_in) + b_in)
      # 输出门
      output_gate = tf.sigmoid(tf.matmul(embedded_input, x_out) + tf.matmul(h, h_out) + b_out)
      # 中间状态
      mid_state = tf.tanh(tf.matmul(embedded_input, x_m) + tf.matmul(h, h_m) + b_m)
      # 计算隐含状态state和输入h
      state = state * forget_gate + input_gate * mid_state
      h = output_gate + tf.tanh(state)
    # 最后遍历的结果就是LSTM的输出
    last_output = h

1.3、文本分类

文本分类问题就是对输入的文本字符串进行分析判断,之后再输出结果。字符串无法直接输入到RNN网络,因此在输入之前需要先对文本拆分成单个词组,将词组进行embedding编码成一个向量,每轮输入一个词组,当最后一个词组输入完毕时得到输出结果也是一个向量。embedding将一个词对应为一个向量,向量的每一个维度对应一个浮点值,动态调整这些浮点值使得embedding编码和词的意思相关。这样网络的输入输出都是向量,再最后进行全连接操作对应到不同的分类即可。

RNN网络不可避免地带来问题就是最后的输出结果受最近的输入较大,而之前较远的输入可能无法影响结果,这就是信息瓶颈问题,为了解决这个问题引入了双向LSTM。双向LSTM不仅增加了反向信息传播,而且每一轮的都会有一个输出,将这些输出进行组合之后再传给全连接层。

另一个文本分类模型就是HAN(Hierarchy Attention Network),首先将文本分为句子、词语级别,将输入的词语进行编码然后相加得到句子的编码,然后再将句子编码相加得到最后的文本编码。而attention是指在每一个级别的编码进行累加前,加入一个加权值,根据不同的权值对编码进行累加。

   

由于输入的文本长度不统一,所以无法直接使用神经网络进行学习,为了解决这个问题,可以将输入文本的长度统一为一个最大值,勉强采用卷积神经网络进行学习,即TextCNN。文本卷积网络的卷积过程采用的是多通道一维卷积,与二维卷积相比一维卷积就是卷积核只在一个方向上移动。例如下左图所示,1×1+5×2+2×2+4×3+3×3+3×4=48,之后卷积核向下移动一格得到45,以此类推。如下右图所示,输入长短不一的多个词汇。首先将其全部填充为六通道的embedding数组,然后采用六通道的一维卷积核从上到下进行卷积,得到一维的数组,然后再经过池化层和全连接层后输出。

    

可以看到CNN网络不能完美处理输入长短不一的序列式问题,但是它可以并行处理多个词组,效率更高,而RNN可以更好地处理序列式的输入,将两者的优势结合起来就构成了R-CNN模型。首先通过双向RNN网络对输入进行特征提取,再使用CNN进一步提取,之后通过池化层将每一步的特征融合在一起,最后经过全连接层进行分类。

无论什么模型都需要使用embedding将输入转化为一个向量,当输入过大时,转化的embedding层参数就会过大,不仅不利于存储,还会造成过拟合,因此需要对embedding层进行压缩。原来的embedding编码是一个参数对应一个输入,例如wait对应参数x1,for对应x2,the对应x3。如果输入过多,编码参数就会很大,可以采用两个参数对组合的方式来编码输入,例如wait对应(x1,x2),for对应(x1,x3)...,这样就可以极大的节省参数的数量,这就是共享压缩

2、通过Text RNN进行文本分类

2.1、数据预处理

在网上下载的文本分类数据集文件如下,分为测试集和训练集数据,每个训练集下有四个文件夹,每个文件夹是一个分类,每个分类有1000个txt文件,每个文件中有一条该分类的文本

     

通过os.walk遍历所有训练集文件,将分类文本通过jieba库拆分成单个词组,用空格分隔。然后将分类文本添加到开头,并用制表符分隔,最后将结果输出到train_segment.txt,

# 将文件中的句子通过jieba库拆分为单个词
def segment_word(input_file, output_file):
  # 循环遍历训练数据集的每一个文件
  for root, folders, files in os.walk(input_file):
    print('root:', root)
    for folder in folders:
      print('dir:', folder)
    for file in files:
      file_dir = os.path.join(root, file)
      with open(file_dir, 'rb') as in_file:
        # 读取文件中的文本
        sentence = in_file.read()
        # 通过jieba函数库将句子拆分为单个词组
        words = jieba.cut(sentence)
        # 文件夹路径最后两个字即为分类名
        content = root[-2:] + '\t'
        # 去除词组中的空格,排除为空的词组
        for word in words:
          word = word.strip(' ')
          if word != '':
            content += word + ' '
      # 换行并将文本写入输出文件
      content += '\n'
      with open(output_file, 'a') as outfile:
        outfile.write(content.strip(' '))

结果如下:

由于一些词组出现次数很少,不具有统计意义,所以需要排除,通过get_list()方法统计每个词组出现的频率。利用python自带的dictionary数据类型可以轻易实现词组数据统计,格式为{"keyword":frequency},frequency记录keyword出现的次数。如果一个词组是新出现的则作为新词条加入词典,否则将frequency值+1。

# 统计每个词出现的频率
def get_list(segment_file, out_file):
  # 通过词典保存每个词组出现的频率
  word_dict = {}
  with open(segment_file, 'r') as seg_file:
    lines = seg_file.readlines()
    # 遍历文件的每一行
    for line in lines:
      line = line.strip('\r\n')
      # 将一行按空格拆分为每个词,统计词典
      for word in line.split(' '):
        # 如果这个词组没有在word_dict词典中出现过,则新建词典项并设为0
        word_dict.setdefault(word, 0)
        # 将词典word_dict中词组word对应的项计数加一
        word_dict[word] += 1
    # 将词典中的列表排序,关键字为列表下标为1的项,且逆序
    sorted_list = sorted(word_dict.items(), key=lambda d: d[1], reverse=True)
    with open(out_file, 'w') as outfile:
      # 将排序后的每条词典项写入文件
      for item in sorted_list:
        outfile.write('%s\t%d\n' % (item[0], item[1]))

统计结果如下:

2.2、数据读入

直接使用词组无法进行编码学习,需要将词组转化为embedding编码,根据刚才生成的train_list列表,按照从前往后的顺序为每个词组编号,如果词组频率小于阈值则排除掉。通过Word_list类来构建训练数据、测试数据的词组对象,在类的构造函数__init__()实现词组的编码。并定义类方法sentence2id将拆分好的句子词组转化为对应的id数组,如果词组列表中没有该词,则将该值置为-1。

在定义类之前首先规定一些超参数供后续使用:

# 定义超参数
embedding_size = 32 # 每个词组向量的长度
max_words = 10 # 一个句子最大词组长度
lstm_layers = 2 # lstm网络层数
lstm_nodes = [64, 64] # lstm每层结点数
fc_nodes = 64 # 全连接层结点数
batch_size = 100 # 每个批次样本数据
lstm_grads = 1.0 # lstm网络梯度
learning_rate = 0.001 # 学习率
word_threshold = 10 # 词表频率门限,低于该值的词语不统计
num_classes = 4 # 最后的分类结果有4类
class Word_list:
  def __init__(self, filename):
    # 用词典类型来保存需要统计的词组及其频率
    self._word_dic = {}
    with open(filename, 'r',encoding='GB2312',errors='ignore') as f:
      lines = f.readlines()
    for line in lines:
      word, freq = line.strip('\r\n').split('\t')
      freq = int(freq)
      # 如果词组的频率小于阈值,跳过不统计
      if freq < word_threshold:
        continue
      # 词组列表中每个词组都是不重复的,按序添加到word_dic中即可,下一个词组id就是当前word_dic的长度
      word_id = len(self._word_dic)
      self._word_dic[word] = word_id

  def sentence2id(self, sentence):
    # 将以空格分割的句子返回word_dic中对应词组的id,若不存在返回-1
    sentence_id = [self._word_dic.get(word, -1)
            for word in sentence.split()]
    return sentence_id

train_list = Word_list(train_list_dir)

定义TextData类来完成数据的读入和管理,在__init__()函数中读取刚才处理好的train_segment.txt文件,根据制表符分割类别标记和句子词组,将类别和句子分别转化为数字id。如果句子的词组超过了最大阈值,则截去后面多余的,如果不够则用-1填充。定义类函数_shuffle_data()用于清洗数据,next_batch()用于按批次返回数据和标签,get_size()用于返回词组总条数。

class TextData:
  def __init__(self, segment_file, word_list):
    self.inputs = []
    self.labels = []
    # 通过词典管理文本类别
    self.label_dic = {'体育': 0, '校园': 1, '女性': 2, '出版': 3}
    self.index = 0

    with open(segment_file, 'r') as f:
      lines = f.readlines()
      for line in lines:
        # 文本按制表符分割,前面为类别,后面为句子
        label, content = line.strip('\r\n').split('\t')[0:2]
        self.content_size = len(content)
        # 将类别转换为数字id
        label_id = self.label_dic.get(label)
        # 将句子转化为embedding数组
        content_id = word_list.sentence2id(content)
        # 如果句子的词组长超过最大值,截取max_words长度以内的id值
        content_id = content_id[0:max_words]
        # 如果不够则填充-1,直到max_words长度
        padding_num = max_words - len(content_id)
        content_id = content_id + [-1 for i in range(padding_num)]
        self.inputs.append(content_id)
        self.labels.append(label_id)
    self.inputs = np.asarray(self.inputs, dtype=np.int32)
    self.labels = np.asarray(self.labels, dtype=np.int32)
    self._shuffle_data()

  # 对数据按照(input,label)对来打乱顺序
  def _shuffle_data(self):
    r_index = np.random.permutation(len(self.inputs))
    self.inputs = self.inputs[r_index]
    self.labels = self.labels[r_index]

  # 返回一个批次的数据
  def next_batch(self, batch_size):
    # 当前索引+批次大小得到批次的结尾索引
    end_index = self.index + batch_size
    # 如果结尾索引大于样本总数,则打乱所有样本从头开始
    if end_index > len(self.inputs):
      self._shuffle_data()
      self.index = 0
      end_index = batch_size
    # 按索引返回一个批次的数据
    batch_inputs = self.inputs[self.index:end_index]
    batch_labels = self.labels[self.index:end_index]
    self.index = end_index
    return batch_inputs, batch_labels

  # 获取词表数目
  def get_size(self):
    return self.content_size

# 训练数据集对象
train_set = TextData(train_segment_dir, train_list)
# print(data_set.next_batch(10))
# 训练数据集词组条数
train_list_size = train_set.get_size()

2.3、构建计算图模型

定义函数create_model来实现计算图模型的构建。首先定义模型输入的占位符,分别为输入文本inputs、输出标签outputs、Dropout的比率keep_prob。

首先构建embedding层,将输入的inputs编码抽取出来拼接成一个矩阵,例如输入[1,8,3]则抽取embeding[1]、embedding[8]和embedding[3]拼接成一个矩阵

接下来构建LSTM网络,这里构建了两层网络,每层的结点数在之前的参数lstm_node[]数组中定义。每个cell的构建通过函数tf.contrib.rnn.BasicLSTMCell实现,之后经过Dropout操作。再将两个cell合并为一个LSTM网络,通过函数tf.nn.dynamic_rnn将输入embedded_inputs输入到LSTM网络中进行训练得到输出rnn_output。这是一个三维数组,第二维表示训练的步数,我们只取最后一维的结果,即下标值为-1.

接下来构建全连接层,通过tf.layers.dense函数定义全连接层,再经过一个dropout操作后将输出映射到类别上,类别的种类的参数num_classes,得到估计值logits

接下来就可以求损失、精确率等评估值了。计算算预测值logits与标签值outputs之间的交叉熵损失值,接下来通过arg_max计算预测值,进而求准确率

接下来定义训练方法,通过梯度裁剪应用到变量上以防止梯度消失。

最后将输入占位符、损失等评估值、其他训练参数返回到调用函数的外部。

# 创建计算图模型
def create_model(list_size, num_classes):
  # 定义输入输出占位符
  inputs = tf.placeholder(tf.int32, (batch_size, max_words))
  outputs = tf.placeholder(tf.int32, (batch_size,))
  # 定义是否dropout的比率
  keep_prob = tf.placeholder(tf.float32, name='keep_rate')
  # 记录训练的总次数
  global_steps = tf.Variable(tf.zeros([], tf.float32), name='global_steps', trainable=False)

  # 将输入转化为embedding编码
  with tf.variable_scope('embedding',
              initializer=tf.random_normal_initializer(-1.0, 1.0)):
    embeddings = tf.get_variable('embedding', [list_size, embedding_size], tf.float32)
    # 将指定行的embedding数值抽取出来
    embedded_inputs = tf.nn.embedding_lookup(embeddings, inputs)

  # 实现LSTM网络
  scale = 1.0 / math.sqrt(embedding_size + lstm_nodes[-1]) / 3.0
  lstm_init = tf.random_uniform_initializer(-scale, scale)
  with tf.variable_scope('lstm_nn', initializer=lstm_init):
    # 构建两层的lstm,每层结点数为lstm_nodes[i]
    cells = []
    for i in range(lstm_layers):
      cell = tf.contrib.rnn.BasicLSTMCell(lstm_nodes[i], state_is_tuple=True)
      # 实现Dropout操作
      cell = tf.contrib.rnn.DropoutWrapper(cell, output_keep_prob=keep_prob)
      cells.append(cell)
    # 合并两个lstm的cell
    cell = tf.contrib.rnn.MultiRNNCell(cells)
    # 将embedded_inputs输入到RNN中进行训练
    initial_state = cell.zero_state(batch_size, tf.float32)
    # runn_output:[batch_size,num_timestep,lstm_outputs[-1]
    rnn_output, _ = tf.nn.dynamic_rnn(cell, embedded_inputs, initial_state=initial_state)
    last_output = rnn_output[:, -1, :]

  # 构建全连接层
  fc_init = tf.uniform_unit_scaling_initializer(factor=1.0)
  with tf.variable_scope('fc', initializer=fc_init):
    fc1 = tf.layers.dense(last_output, fc_nodes, activation=tf.nn.relu, name='fc1')
    fc1_drop = tf.contrib.layers.dropout(fc1, keep_prob)
    logits = tf.layers.dense(fc1_drop, num_classes, name='fc2')

  # 定义评估指标
  with tf.variable_scope('matrics'):
    # 计算损失值
    softmax_loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=outputs)
    loss = tf.reduce_mean(softmax_loss)
    # 计算预测值,求第1维中最大值的下标,例如[1,1,5,3,2] argmax=> 2
    y_pred = tf.argmax(tf.nn.softmax(logits), 1, output_type=tf.int32)
    # 求准确率
    correct_prediction = tf.equal(outputs, y_pred)
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

  # 定义训练方法
  with tf.variable_scope('train_op'):
    train_var = tf.trainable_variables()
    # for var in train_var:
    #   print(var)
    # 对梯度进行裁剪防止梯度消失或者梯度爆炸
    grads, _ = tf.clip_by_global_norm(tf.gradients(loss, train_var), clip_norm=lstm_grads)
    # 将梯度应用到变量上去
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
    train_op = optimizer.apply_gradients(zip(grads, train_var), global_steps)

  # 以元组的方式将结果返回
  return ((inputs, outputs, keep_prob),
      (loss, accuracy),
      (train_op, global_steps))

# 调用构建函数,接收解析返回的参数
placeholders, matrics, others = create_model(train_list_size, num_classes)
inputs, outputs, keep_prob = placeholders
loss, accuracy = matrics
train_op, global_steps = others

2.4、进行训练

通过Session运行计算图模型,从train_set中按批次获取训练集数据并填充占位符,运行sess.run,获取损失值、准确率等中间值打印

# 进行训练
init_op = tf.global_variables_initializer()
train_keep_prob = 0.8    # 训练集的dropout比率
train_steps = 10000

with tf.Session() as sess:
  sess.run(init_op)

  for i in range(train_steps):
    # 按批次获取训练集数据
    batch_inputs, batch_labels = train_set.next_batch(batch_size)
    # 运行计算图
    res = sess.run([loss, accuracy, train_op, global_steps],
            feed_dict={inputs: batch_inputs, outputs: batch_labels,
                 keep_prob: train_keep_prob})
    loss_val, acc_val, _, g_step_val = res
    if g_step_val % 20 == 0:
      print('第%d轮训练,损失:%3.3f,准确率:%3.5f' % (g_step_val, loss_val, acc_val))

在我的数据集进行一万轮训练后,训练集的准确率在90%左右徘徊

源代码及相关数据文件:https://github.com/SuperTory/MachineLearning/tree/master/TextRNN

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数据结构与算法教程》、《Python加密解密算法与技巧总结》、《Python编码操作技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

(0)

相关推荐

  • python编写朴素贝叶斯用于文本分类

    朴素贝叶斯估计 朴素贝叶斯是基于贝叶斯定理与特征条件独立分布假设的分类方法.首先根据特征条件独立的假设学习输入/输出的联合概率分布,然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y. 具体的,根据训练数据集,学习先验概率的极大似然估计分布 以及条件概率为 Xl表示第l个特征,由于特征条件独立的假设,可得 条件概率的极大似然估计为 根据贝叶斯定理 则由上式可以得到条件概率P(Y=ck|X=x). 贝叶斯估计 用极大似然估计可能会出现所估计的概率为0的情况.后影响到后验概率结果

  • TensorFlow平台下Python实现神经网络

    本篇文章主要通过一个简单的例子来实现神经网络.训练数据是随机产生的模拟数据集,解决二分类问题. 下面我们首先说一下,训练神经网络的一般过程: 1.定义神经网络的结构和前向传播的输出结果 2.定义损失函数以及反向传播优化的算法 3.生成会话(Session)并且在训练数据上反复运行反向传播优化算法 要记住的一点是,无论神经网络的结构如何变化,以上三个步骤是不会改变的. 完整代码如下: import tensorflow as tf #导入TensorFlow工具包并简称为tf from numpy

  • python使用RNN实现文本分类

    本文实例为大家分享了使用RNN进行文本分类,python代码实现,供大家参考,具体内容如下 1.本博客项目由来是oxford 的nlp 深度学习课程第三周作业,作业要求使用LSTM进行文本分类.和上一篇CNN文本分类类似,本此代码风格也是仿照sklearn风格,三步走形式(模型实体化,模型训练和模型预测)但因为训练时间较久不知道什么时候训练比较理想,因此在次基础上加入了继续训练的功能. 2.构造文本分类的rnn类,(保存文件为ClassifierRNN.py) 2.1 相应配置参数因为较为繁琐,

  • Python编程实现的简单神经网络算法示例

    本文实例讲述了Python编程实现的简单神经网络算法.分享给大家供大家参考,具体如下: python实现二层神经网络 包括输入层和输出层 # -*- coding:utf-8 -*- #! python2 import numpy as np #sigmoid function def nonlin(x, deriv = False): if(deriv == True): return x*(1-x) return 1/(1+np.exp(-x)) #input dataset x = np.

  • 神经网络(BP)算法Python实现及应用

    本文实例为大家分享了Python实现神经网络算法及应用的具体代码,供大家参考,具体内容如下 首先用Python实现简单地神经网络算法: import numpy as np # 定义tanh函数 def tanh(x): return np.tanh(x) # tanh函数的导数 def tan_deriv(x): return 1.0 - np.tanh(x) * np.tan(x) # sigmoid函数 def logistic(x): return 1 / (1 + np.exp(-x)

  • Python实现的三层BP神经网络算法示例

    本文实例讲述了Python实现的三层BP神经网络算法.分享给大家供大家参考,具体如下: 这是一个非常漂亮的三层反向传播神经网络的python实现,下一步我准备试着将其修改为多层BP神经网络. 下面是运行演示函数的截图,你会发现预测的结果很惊人! 提示:运行演示函数的时候,可以尝试改变隐藏层的节点数,看节点数增加了,预测的精度会否提升 import math import random import string random.seed(0) # 生成区间[a, b)内的随机数 def rand(

  • Python与人工神经网络:使用神经网络识别手写图像介绍

    人体的视觉系统是一个相当神奇的存在,对于下面的一串手写图像,可以毫不费力的识别出他们是504192,轻松到让人都忘记了其实这是一个复杂的工作. 实际上在我们的大脑的左脑和右脑的皮层都有一个第一视觉区域,叫做V1,里面有14亿视觉神经元.而且,在我们识别上面的图像的时候,工作的不止有V1,还有V2.V3.V4.V5,所以这么一看,我们确实威武. 但是让计算机进行模式识别,就比较复杂了,主要困难在于我们如何给计算机描述一个数字9在图像上应该是怎样的,比如我们跟计算机说,9的上面是一个圈,下右边是1竖

  • Python实现的NN神经网络算法完整示例

    本文实例讲述了Python实现的NN神经网络算法.分享给大家供大家参考,具体如下: 参考自Github开源代码:https://github.com/dennybritz/nn-from-scratch 运行环境 Pyhton3 numpy(科学计算包) matplotlib(画图所需,不画图可不必) sklearn(人工智能包,生成数据使用) 计算过程 输入样例 none 代码实现 # -*- coding:utf-8 -*- #!python3 __author__ = 'Wsine' im

  • python实现BP神经网络回归预测模型

    神经网络模型一般用来做分类,回归预测模型不常见,本文基于一个用来分类的BP神经网络,对它进行修改,实现了一个回归模型,用来做室内定位.模型主要变化是去掉了第三层的非线性转换,或者说把非线性激活函数Sigmoid换成f(x)=x函数.这样做的主要原因是Sigmoid函数的输出范围太小,在0-1之间,而回归模型的输出范围较大.模型修改如下: 代码如下: #coding: utf8 '''' author: Huangyuliang ''' import json import random impo

  • Python使用循环神经网络解决文本分类问题的方法详解

    本文实例讲述了Python使用循环神经网络解决文本分类问题的方法.分享给大家供大家参考,具体如下: 1.概念 1.1.循环神经网络 循环神经网络(Recurrent Neural Network, RNN)是一类以序列数据为输入,在序列的演进方向进行递归且所有节点(循环单元)按链式连接的递归神经网络. 卷积网络的输入只有输入数据X,而循环神经网络除了输入数据X之外,每一步的输出会作为下一步的输入,如此循环,并且每一次采用相同的激活函数和参数.在每次循环中,x0乘以系数U得到s0,再经过系数W输入

  • Python之使用adb shell命令启动应用的方法详解

    一直有一个心愿希望可以用Python做安卓自动化功能测试,在一步步摸索中,之前是用monkeyrunner,但是发现对于控件ID的使用非常具有局限性,尤其是ID的内容不便于区分 具有重复性时,后面又发现Uiautomator可以对resorceId.text.packageName等元素进行定位,也找到了xiaochong这位大神关于uiautomator的封装包,链接如下: https://github.com/xiaocong/uiautomator 做为一个小白,这一切都需要摸索,在克服了

  • Python实现从文件中加载数据的方法详解

    前几篇都是手动录入或随机函数产生的数据.实际有许多类型的文件,以及许多方法,用它们从文件中提取数据来图形化. 比如之前python基础(12)介绍打开文件的方式,可直接读取文件中的数据,扩大了我们的数据来源.下面,将展示几种方法. 我们将使用内置的 csv 模块加载CSV文件 CSV文件是一种特殊的文本文件,文件中的数据以逗号作为分隔符,很适合进行数据的解析.先用excle建立如下表格和数据,另存为csv格式文件,放到代码目录下. 包含在Python标准库中自带CSV 模块,我们只需要impor

  • Python快速从视频中提取视频帧的方法详解

    目录 1.抽取视频帧 2.多线程方法 3.整体代码 补充 Python快速提取视频帧(多线程) 今天介绍一种从视频中抽取视频帧的方法,由于单线程抽取视频帧速度较慢,因此这里我们增加了多线程的方法. 1.抽取视频帧 抽取视频帧主要使用了 Opencv 模块. 其中: camera = cv2.Videocapture( ) ,函数主要是通过调用笔记本内置摄像头读取视频帧: res, image = camera.read( ) 函数主要是按帧读取视频,返回值 “res” 是布尔型,成功读取返回 T

  • Python 3.6 性能测试框架Locust安装及使用方法(详解)

    背景 Python3.6 性能测试框架Locust的搭建与使用 基础 python版本:python3.6 开发工具:pycharm Locust的安装与配置 点击"File"→"setting" 点击"setting",进入设置窗口,选择"Project Interpreter" 点击"+" 输入需要"Locust",点击"Install Package" 安装完成

  • 对Python 多线程统计所有csv文件的行数方法详解

    如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Thread): #用于统计csv文件的行数的线程类 def __init__(self,path): threading.Thread.__init__(self) #父类初始化 self.path=path #路径 self.line=-1 #统计行数 def run(self): reader =

  • 对python中xlsx,csv以及json文件的相互转化方法详解

    最近需要各种转格式,这里对相关代码作一个记录,方便日后查询. xlsx文件转csv文件 import xlrd import csv def xlsx_to_csv(): workbook = xlrd.open_workbook('1.xlsx') table = workbook.sheet_by_index(0) with codecs.open('1.csv', 'w', encoding='utf-8') as f: write = csv.writer(f) for row_num

  • 对Python中一维向量和一维向量转置相乘的方法详解

    在Python中有时会碰到需要一个一维列向量(n*1)与另一个一维列向量(n*1)的转置(1*n)相乘,得到一个n*n的矩阵的情况.但是在python中, 我们发现,无论是".T"还是"np.transpose"都无法实现一维向量的转置,相比之下,Matlab一句" a' "就能实现了. 那怎么实现呢?我找了个方法.请看: 即,我们把向量reshape一下,如此便实现了一维向量与一维向量转置相乘为矩阵的目的. 若大家有其他方法望告知. 以上这篇对

  • 对python numpy.array插入一行或一列的方法详解

    如下所示: import numpy as np a = np.array([[1,2,3],[4,5,6],[7,8,9]]) b = np.array([[0,0,0]]) c = np.insert(a, 0, values=b, axis=0) d = np.insert(a, 0, values=b, axis=1) print(c) print(d) >>c [[0 0 0] [1 2 3] [4 5 6] [7 8 9]] >>d [[0 1 2 3] [0 4 5

  • 对Python正则匹配IP、Url、Mail的方法详解

    如下所示: """ Created on Thu Nov 10 14:07:36 2016 @author: qianzhewoniuqusanbu """ import re def RegularMatchIP(ip):     '''进行正则匹配ip,加re.IGNORECASE是让结果返回bool型'''     pattern=re.match(r'\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?

随机推荐