【深度学习框架简单梳理】电影评论二分类问题


0x00 前言

  最近开始学习深度学习,所以打算以写博客的形式来记录自己的学习过程。
  本篇博客的目的是梳理熟悉深度学习的整体框架神经网络模型及代码的构建以及加深深度学习整个过程的理解。基于目的,选择了较为简单的电影评论分类问题为例子。参考的书籍是 [美]Francois Chollet 著的《Python深度学习》,结合书本内容的同时也会提出我自己对部分细节的理解和总结。
  运行环境:

Name Version
python 3.6
keras 2.2.4
tensorflow-gpu 1.14.0
Numpy 1.16.2
cuda 10.1
cudnn 7.6.5


0x01 整体概述


在这里插入图片描述

图1-模型训练过程图


  【问题描述】:电影评论二分类想实现的工作其实就是将评论分为两个阵营——正面和负面。
  【实现过程】:评论数据输入训练好的神经网络模型,得出一个预测值(此处预测值为正面或者负面),期待该预测值就为真实目标值或者为真的概率尽可能高。那么重点就是如何训练神经网络模型,据流程图,模型由若干个层组成,而每一层都对输入的数据做某种变换,最后得出一个预测值(呵呵很神奇),当然一开始这个预测值很可能不准确,那么到底有多不准确,由损失值来衡量,损失值可以理解为预测值到真实值之间的距离(通常距离越小越好),而损失函数就是计算这个距离用的。我们要训练的对象具体来说就是各层中的权重参数w,权重参与数据变换的过程,所以理论上取一组合适的权重,可以使得预测值最准确。那么如何得到合适的权重就是优化器的工作,优化器会依据损失值来更新权重。总结一下就是以下几个步骤:

  (1)将数据输入神经网络模型,输出预测值
  (2)损失函数依据真实目标值计算损失值
  (3)优化器依据损失值更新权重

于是不断地输入数据,反复迭代,重复以上步骤就会得到一组较为合适的权重。当然会存在过拟合现象,先按下不表。
  至此,就是模型训练的大致流程。不过依旧存在很多疑问,例如全连接层是干什么的?二元交叉熵是什么?优化器具体是怎么工作的?等等。下面展开来讲。

0x02 细节展开

2.1 数据预处理

  前面的整体概述中没有提到数据处理的有关内容,在实际应用中,数据处理是一块重要的部分。因为输入模型的数据需要符合统一格式和特定的数据结构,而不做处理的原始数据往往不符合模型输入的条件,所以要进行数据预处理。

2.1.1 获取数据

  本例数据直接来自IMDB数据库

from keras.datasets import imdb

# 加载数据
# 所加载的数据集其实是二维列表
# 每条评论是由其单词的整数索引构成的向量
(train_data, train_lables), (test_data, test_lables) = imdb.load_data(num_words=10000)  # 10000意思是只保留最常出现的前10000单词

书本引用:
  参数num_words=10000的意思是仅保留训练数据中前10000个最常出现的单词。低频单词将被舍弃。这样得到的向量数据不会太大,便于处理。

  trian_data、test_data: 由评论组成的二维列表(samples,features),第一维是样本批量维度,第二维是评论。每一条评论都是由其单词的整数索引构成的一维向量(一个单词对应一个整数,这个整数不会超过9999)

  train_lables、test_lables: 0、1组成的一维列表,0代表负面评论,1代表正面评论。数据标签,所谓的真实目标值,与每条评论呈一一对应关系。

2.1.2 处理数据

import numpy as np

# 准备数据(合适的格式)
# 因为神经网络需要传入张量的数据结构,所以要将数据向量化,将所有评论都向量化到一样的维度此处化到10000维,因为根据最常用的前10000的单词,单词所对应的序号最大为9999
# 对列表进行one-hot编码,将其转化为0和1组成的向量

def vectorize_sequences(sequences, dimension=10000):  # 这里的 sequence 其实是传入的(训练集/测试集)
    results = np.zeros((len(sequences), dimension))   # 创建零矩阵(二维张量)
    for i, sequence in enumerate(sequences):
        # 这里其实有点桶排的味道,将下标索引为该值的元素置1,表示有该值,其余为0
        results[i, sequence] = 1.                       # [1.]表示此处数据类型为浮点
    return results
    
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

# 将标签也向量化,因为标签本来就是一维的向量了,所以直接转化成张量的数据结构就可了
y_train = np.asarray(train_lables).astype('float32')
y_test = np.asarray(test_lables).astype('float32')

  代码解释请参考注释☝

  此处之所以将数据类型转换为浮点型,给出我自己的理解:拓展学习空间
  将数据集类型转化为浮点型以后,在训练过程中的权重、损失值等也都从整数向浮点转变。而权重就是神经网络学习到的东西,转为浮点以后,它能够表示的范围就变大了,也就拓展了学习空间。这里的权重其实是张量矩阵,下文再展开来讲。

2.2 神经网络模型搭建

  在讲解以下内容的时候,可能会有这样的疑问:为什么要这样那样搭建模型就可以了?
  事实上根据不同的实际问题,要搭建不同的神经网络,而为什么要这样搭建,更多的是经验之谈。虽然存在一些原则性的指导,可以指导你采取某种模型架构更加合适,但是很难严谨科学逻辑地推出具体哪种模型是最好的。所以深度学习更偏向是一门工程性科学,需要不断实践。
  本篇博客的目的也不是帮助你建立搭建模型的直觉,所以你要知道,接下来针对电影评论分类问题所搭建的模型,是已经已知且比较合适的。当然也可以采取其他不同的尝试。

2.2.1 模型架构

  这里采用Sequential类来做层的线性堆叠架构,这是目前最常见的网络架构。所谓线性堆叠,从前文的流程图可以看出,是由单一输入映射到单一输出,再依次顺序连接各层。“深度学习”的深度也就体现在层的堆叠上。

from keras import models

model = models.Sequential()

  这样子我们建立了一个模型的框架,之后就可以往这个框架中添加层。当然,除了线性堆叠的架构,还有其他各种各样的有向无环的拓扑架构可以采用。

2.2.2 层

  对于电影评论二分类问题,此处使用全连接层(fully connected layer,也叫密集层 dense layer),激活函数采用relu、sigmoid。

from keras import layers

# Dense的第一个参数是该层的输出维度,也可以认为是该层的学习空间
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))  # 这里的10000指的是每个输入样本数据的维度,不包含样本数量的维度
model.add(layers.Dense(16, activation='relu'))  # 从第二层开始,就不用写输入样本数据的维度,因为自动根据上一层进行调节
model.add(layers.Dense(1, activation='sigmoid'))

  代码解释请参考注释☝

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值