深度学习基础

文章目录

  • 深度学习基础
    • 1、加载IMDB数据集
    • 2、准备数据
    • 3、构建网络
      • 3.1、定义模型
      • 3.2编译模型
      • 3.3配置优化器
      • 3.4使用定义的损失和指标
    • 4验证
      • 4.1 预留验证集
      • 4.2 训练模型
      • 4.3绘制训练损失和验证损失
      • 4.4绘制训练精度和验证精度
      • 4.5重新训练一个模型

之前学习了一些深度学习的概念,以及神经网络的一些数学基础,在此以电影评论分类的二分类问题进一步学习深度学习的内容。

1、加载IMDB数据集

#1、加载IMDB数据集
from keras.datasets import imdb #IMDB数据(互联网电影数据库)集是已经经过预处理被转换为整数序列的数据集,整数代表字典中的某个单词
(train_data, train_labels),(test_data, test_labels)=imdb.load_data(num_words=1000)#num_words=10000保留数据中最常出现的前1000个单词
train_data[0]#输出训练集单词索引,单词索引不会超过1000
#列表索引为0-25000,每个列表整数的个数是随机的
train_labels[0]#输出训练集标签
#列表索引为0-25000,train_labels和test_labels的取值为0(负面negative)和1(positive)

标签输出结果:

1
max ([max(sequence) for sequence in train_data])#输出最大索引
999
word_index = imdb.get_word_index()#将单词索引解码为英文单词
reverse_word_index = dict([(value,key) for (key,value) in word_index.items()])#键值颠倒将整数索引映射为单词
decoded_reviw = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])#将评论解码,索引减去3是因为0,1,2,3是起始序列为padding填充,他们为‘unknown’未知词保留的索引

2、准备数据

通常要对原始数据大量的预处理以便将其转化为张量再输入到神经网络中。

单词序列可以编码成二进制向量也可以编码成其他。

# 2、准备数据
import numpy as np
def vectorize_sequences(sequences,dimension=1000):#将随机长度整数序列编码为指定尺寸的二进制矩阵,指定的值的大小要大于等于序列输出最大索引,小于数组可调用的计算内存results = np.zeros((len(sequences), dimension)).astype('float32')#此处若不指定astype会默认为'float64',因此需要将其指定为惯用'float32'for i,  sequence in enumerate(sequences):#枚举序列循环results[i,sequence]=1.#指定索引赋值为1return results
x_train = vectorize_sequences(train_data)#将训练数据向量化
x_test = vectorize_sequences(test_data)#将测试数据向量化

在准备数据过程中,例如回归问题,将取值范围差异较大的数据输入到神经网络中是不合理的,需要对数据进行标准化,即对输入的每个特征减去均值除以标准差(归一化数据均值为0,标准差为1)。
mean=train_data.mean(axis=0)
train_data -=mean
std = train_data.std(axis=0)
train_data /=std

x_train#显示转化为array形式的 样本
array([[0., 1., 1., ..., 0., 0., 0.],[0., 1., 1., ..., 0., 0., 0.],[0., 1., 1., ..., 0., 0., 0.],...,[0., 1., 1., ..., 0., 0., 0.],[0., 1., 1., ..., 0., 0., 0.],[0., 1., 1., ..., 0., 0., 0.]], dtype=float32)
#将标签向量化
y_train = np.asarray(train_labels).astype('float32')#此处标签本来就为0和1,故只需用numpy操作将其转化为数组即可
y_test = np.asarray(test_labels).astype('float32')

标签向量化的方法有两种 ,将标签列表转化为 整数张量,或者使用one-hot(分类编码categorical encoding)。
from keras.utils.np_utils import to_categorical
one_hot_test_labels = to_categorical(test_labels)

y_train#输出向量化的y_train
array([1., 0., 0., ..., 0., 1., 0.], dtype=float32)

3、构建网络

3.1、定义模型

二分类问题网络的最后一层应该只有一个单元,并且采用’sigmoid’激活,网络输出应该为0~1范围内的标量,表示概率。前两个层隐层单元可以选更多或者更少。

# 3、构建网络
# 3.1、定义模型
from keras import models
from keras import layers
model = models.Sequential()#模块连续,使模块层间输出输入的张量自适应(因为需要将同一个模型多次实例化)
model.add(layers.Dense(16,activation = 'relu',input_shape=(1000,)))#向模型中添加逐元激活密集层,输出维度为32,采用'relu'非线性激活,输入为1000维(1000行任意列)
model.add(layers.Dense(16,activation = 'relu'))#采用了models.Sequential(),故没有指定输入维度,自适应为32维
model.add(layers.Dense(1,activation = 'sigmoid'))#此层为最后一层采用'sigmoid'激活,仅仅包含一个隐藏单元,后续使用的损失函数最好是二元交叉熵(binary_crossentropy)

三个层的输出维度16,16,1也叫层隐藏单元个数只能相等或者递减,如果中间层较小会造成信息瓶颈(大部分非全部的数据被压缩在这个较小的层,最后网络验证精度也恶化)。
输入数据维2维张量通常用密集层Dense,3维张量用循环层LSTM,4维张量用二维卷积层Conv2D。
在最后一层的激活上多分类问题采用softmax激活,区别于二分零问题的1个隐藏单元,隐藏单元数为分类数,最后输出不同输出类别的概率分布,回归问题不采用非线性激活使网络学会预测任意范围内的值。


神经网络的层结构:

dense只包含两个线性运算,张量点积和加法:

output=dot(inpute,W)+boutput\,\,=\,\,dot\left( inpute,W \right) \,\,+\,\,b output=dot(inpute,W)+b
多个线性层堆叠实现的仍然是线性运算,不会扩展假设空间,故通常通过添加非线性或激活函数来丰富层的假设空间来充分彰显层的优势。

W(权重矩阵)和b都是张量,为dense的中心kernel和偏移bias属性。随机初始化时权重矩阵取较小的随机值,这个起点权重没有任何意义,在训练过程中W受训练反馈调节。

inpute = sigmoid(a1)#激活函数取sigmoid函数,a1为要训练的数据
output = np.dot(inpute,W)+b#同a1可得第二层计算

拓展神经网络中的激活函数:

阶跃函数:

import numpy as np
import matplotlib.pylab as plt
def step_func1(x):return np.array(x>0,dtype=np.int)#将布尔型转换为int型,大于零对应true转换为1,小于零false转换为0
x = np.arange(−10.0,10.0,0.1)#在−10到10的范围内以1为单位生成numpy数组
y = step_func1(x)#y值取调用函数得到的值
plt.plot(x,y)#画布横纵轴分别为xy
plt.ylim(−0.01,1.01)#画布中y轴范围指定为从−0.01到1.01
plt.show()

sigmoid函数是平滑的连续的,感知机使用的阶跃函数是神经元之间流动的是0或1的二元信号,而神经网络中流动的是连续的实数值信号:
h(x)=11+e−xh\left( x \right) =\frac{1}{1+e^{-x}} h(x)=1+e−x1​

import numpy as np
import matplotlib.pylab as plt
#参数x取值为numpy数组时也能够正常计算
def sigmoid(x):return 1/(1+np.exp(−x))
x = np.arange(−10,10,0.1)#x轴范围
y = sigmoid(x)
plt.plot(x,y)
plt.ylim(−0.1,1.1)#y轴范围
plt.show()

relu函数:

relu 函数主要表示当输入x 大于0 时输出x,输入x 小于0 时输出0

import numpy as np
import matplotlib.pylab as plt
#relu函数
def relu(x):return np.maximum(0,x)#输入大于0输出该值,输入小于0输出0(使用numpy中的maximum函数,该函数可以从输入的数值中选择大的值输出)
x = np.arange(-10,10,1)#x范围和缩进
y = relu(x)
plt.plot(x,y)
plt.ylim(-2,10.1)#y范围
plt.show()

3.2编译模型

# 3.2编译模型model.compile(optimizer='rmsprop',#选择优化器loss='binary_crossentropy',#选择损失函数二元交叉熵metrics=['accuracy'])#选择度量

编译模型,将Keras内置的优化器,损失函数和度量指标作为字符串输入,解决实际问题时常常将将这些参数以自定义函数传入。

3.3配置优化器

# 3.3配置优化器
from keras import optimizers
model.compile(optimizer=optimizers.RMSprop(lr=0.001),#向optimizer参数传入优化器类实例来实现优化loss='binary_crossentropy',metrics=['accuracy'])

3.4使用定义的损失和指标

# 3.4使用定义的损失和指标
from keras import losses
from keras import metrics
model.compile(optimizer=optimizers.RMSprop(lr=0.001),loss=losses.binary_crossentropy,#向loss参数传入函数对象二元交叉熵来实现损失metrics=[metrics.binary_accuracy])#向metrics参数传入函数对象二元精确度来实现度量

在多分类问题中损失函数一般选择分类交叉熵categorical_crossentropy,来衡量网络输出的概率分布和标签的真实概率分布之间的距离,通过将这两个分布距离最小化使输出结果尽可能接近真实值。

在回归 问题中,损失函数选择均方误差mse来最小化预测值与目标值之差的平方

4验证

4.1 预留验证集

# 4验证
#4.1 预留验证集
x_val = x_train[:1000]# 预留验证数据
partial_x_train = x_train[1000:]# 预留训练数据
y_val = y_train[:1000]# 预留验证标签
partial_y_train = y_train[1000:]#预留训练标签
#将原始数据留出1000个作为验证集来监控新数据上的精度

4.2 训练模型

# 4.2 训练模型
history = model.fit(partial_x_train,#训练数据partial_y_train,#训练标签epochs=20,#模型训练20个伦次batch_size=512,#512个样本组成小批量validation_data=(x_val, y_val))#将验证数据与标签传入参数validation_data
#fit返回了一个history对象,它包含一个成员history.history,这个成员是一个字典包含4个监控指标,训练损失、验证损失,训练精度、'loss', 'binary_accuracy', 'val_loss', 'val_binary_accuracy'

训练结果:

Epoch 1/20
47/47 [==============================] - 1s 15ms/step - loss: 0.6133 - binary_accuracy: 0.6610 - val_loss: 0.4261 - val_binary_accuracy: 0.8220
Epoch 2/20
47/47 [==============================] - 0s 4ms/step - loss: 0.3944 - binary_accuracy: 0.8370 - val_loss: 0.3476 - val_binary_accuracy: 0.8560
Epoch 3/20
47/47 [==============================] - 0s 4ms/step - loss: 0.3367 - binary_accuracy: 0.8615 - val_loss: 0.3356 - val_binary_accuracy: 0.8590
Epoch 4/20
47/47 [==============================] - 0s 4ms/step - loss: 0.3227 - binary_accuracy: 0.8666 - val_loss: 0.3217 - val_binary_accuracy: 0.8620
Epoch 5/20
47/47 [==============================] - 0s 4ms/step - loss: 0.3057 - binary_accuracy: 0.8756 - val_loss: 0.3161 - val_binary_accuracy: 0.8630
Epoch 6/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2974 - binary_accuracy: 0.8790 - val_loss: 0.3156 - val_binary_accuracy: 0.8610
Epoch 7/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2998 - binary_accuracy: 0.8757 - val_loss: 0.3146 - val_binary_accuracy: 0.8650
Epoch 8/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2923 - binary_accuracy: 0.8794 - val_loss: 0.3309 - val_binary_accuracy: 0.8480
Epoch 9/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2876 - binary_accuracy: 0.8815 - val_loss: 0.3145 - val_binary_accuracy: 0.8610
Epoch 10/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2806 - binary_accuracy: 0.8832 - val_loss: 0.3131 - val_binary_accuracy: 0.8600
Epoch 11/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2756 - binary_accuracy: 0.8879 - val_loss: 0.3116 - val_binary_accuracy: 0.8590
Epoch 12/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2752 - binary_accuracy: 0.8880 - val_loss: 0.3311 - val_binary_accuracy: 0.8500
Epoch 13/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2697 - binary_accuracy: 0.8914 - val_loss: 0.3194 - val_binary_accuracy: 0.8620
Epoch 14/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2672 - binary_accuracy: 0.8906 - val_loss: 0.3114 - val_binary_accuracy: 0.8630
Epoch 15/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2583 - binary_accuracy: 0.8949 - val_loss: 0.3127 - val_binary_accuracy: 0.8630
Epoch 16/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2434 - binary_accuracy: 0.9015 - val_loss: 0.3159 - val_binary_accuracy: 0.8610
Epoch 17/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2462 - binary_accuracy: 0.9020 - val_loss: 0.3195 - val_binary_accuracy: 0.8600
Epoch 18/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2332 - binary_accuracy: 0.9066 - val_loss: 0.3165 - val_binary_accuracy: 0.8590
Epoch 19/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2257 - binary_accuracy: 0.9097 - val_loss: 0.3216 - val_binary_accuracy: 0.8600
Epoch 20/20
47/47 [==============================] - 0s 4ms/step - loss: 0.2289 - binary_accuracy: 0.9075 - val_loss: 0.3286 - val_binary_accuracy: 0.8550

下面 输出一下这些指标:

history_dict = history.history
history_dict.keys()#history对象,它包含一个成员history.history,这个成员是一个字典包含4个监控指标

结果如下:

dict_keys(['loss', 'binary_accuracy', 'val_loss', 'val_binary_accuracy'])

4.3绘制训练损失和验证损失

# 4.3绘制训练损失和验证损失
import matplotlib.pyplot as plt
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(loss_values) + 1)#以轮次为步距
plt.plot(epochs, loss_values, 'bo', label='Training loss')#bo蓝色圆点
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')#蓝色实线
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

由图,训练损失随轮次的进行而减小,体现了梯度下降的预期结果,验证损失出现波动的情况,几乎在第7轮达到最佳,模型在训练数据上的表现越来越好(损失一直减小),而在新的验证数据上表现变差(损失转折增大),说明模型在第七轮前是较好的模型。

4.4绘制训练精度和验证精度

# 4.4绘制训练精度和验证精度
plt.clf()   # 清空图像
acc = history_dict['binary_accuracy']
val_acc = history_dict['val_binary_accuracy']plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('accuracy')
plt.legend()
plt.show()

由图,训练精度随轮次的进行而增大,验证损失出现波动的情况,几乎在第7轮达到最佳,并且发现由于对训练数据过度优化,在第四轮时学到的表示仅针对训练数据,模型在训练数据表现越来越好,但是逐渐脱离验证数据表现,出现过拟合,模型无法泛化到新的数据中。拟合过程和泛化是此消彼长的,在实际中需要根据实际问题来折中二者。

4.5重新训练一个模型

#4.5重新训练一个模型
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(1000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])model.fit(x_train, y_train, epochs=4, batch_size=512)#伦次变为4次
results = model.evaluate(x_test, y_test)
results

为了防止过拟合我们可以在第4轮之后停止训练

Epoch 1/4
49/49 [==============================] - 1s 3ms/step - loss: 0.6231 - accuracy: 0.6756
Epoch 2/4
49/49 [==============================] - 0s 3ms/step - loss: 0.3992 - accuracy: 0.8436
Epoch 3/4
49/49 [==============================] - 0s 3ms/step - loss: 0.3369 - accuracy: 0.8653
Epoch 4/4
49/49 [==============================] - 0s 4ms/step - loss: 0.3209 - accuracy: 0.8696
782/782 [==============================] - 1s 816us/step - loss: 0.3372 - accuracy: 0.8580
[0.3372243046760559, 0.8580399751663208]

参考:《python 深度学习》

python-三层神经网络的分类回归问题相关推荐

  1. python卷积神经网络回归预测_回归[keras]的一维卷积神经网络,做

    在上一篇博客里我介绍了如何利用keras对一个给定的数据集来完成多分类任务. 100%的分类准确度验证了分类模型的可行性和数据集的准确度. 在这篇博客当中我将利用一个稍加修改的数据集来完成线性回归任务 ...

  2. python卷积神经网络多元分类_CV4-卷积神经网络之多元分类(剪刀石头布)

    目录 这里以剪刀石头布为例.具体一些细节已经在CV1-CV3中详细解释过. 一.多元分类模型 1.准备数据集 下载代码: 训练集数据 wget --no-check-certificate \ htt ...

  3. 使用python构建三层神经网络、softmax函数

    [机器学习]使用python手写三层神经网络 输入层到第一层的传递表示 第一层到第二层的传递表示 第二层到第三层的传递表示 全过程传递表示代码 输入层到第一层的传递表示 首先看输入层到第一层的第一个神 ...

  4. AI:神经网络调参(数据、层数、batch大小,学习率+激活函数+正则化+分类/回归)并进行结果可视化

    AI:神经网络调参(数据.层数.batch大小,学习率+激活函数+正则化+分类/回归)并进行结果可视化 目录 神经网络调参(数据.层数.batch大小,学习率+激活函数+正则化+分类/回归)并进行结果 ...

  5. id3决策树 鸢尾花 python_机器学习之分类回归树(python实现CART)

    机器学习之分类回归树(python实现CART) 之前有文章介绍过决策树(ID3).简单回顾一下:ID3每次选取最佳特征来分割数据,这个最佳特征的判断原则是通过信息增益来实现的.按照某种特征切分数据后 ...

  6. Python搭建tensorflow三层神经网络

    Python搭建tensorflow三层神经网络的小例子 import tensorflow as tf import numpy as np import matplotlib.pyplot as ...

  7. [Python人工智能] 四.TensorFlow创建回归神经网络及Optimizer优化器

    从本篇文章开始,作者正式开始研究Python深度学习.神经网络及人工智能相关知识.前一篇文章讲解了TensorFlow基础和一元直线预测的案例,以及Session.变量.传入值和激励函数:这篇文章将详 ...

  8. python实现三层神经网络 (BP)

    三层神经网络 (numpy实现) 文件目录 线性层 前向传播公式: WX+bWX+bWX+b 代码 def forward(self, X):return np.matmul(X, self.W) + ...

  9. Python实现PSO粒子群优化循环神经网络LSTM分类模型项目实战

    说明:这是一个机器学习实战项目(附带数据+代码+文档+视频讲解),如需数据+代码+文档+视频讲解可以直接到文章最后获取. 1.项目背景 PSO是粒子群优化算法(Particle Swarm Optim ...

最新文章

  1. 解决 mac ox 终端显示bogon 的问题
  2. JDK6u25里添加的按线程统计分配内存量: JMX
  3. 【SPFA】Party(jzoj 1328)
  4. java方法示例注释 @_Java 8中的功能接口是什么? @功能注释和示例
  5. [SD2.0大会]在大型企业中领导敏捷--开发团队领导所必需的技能
  6. dump java 分析工具,java内存分析工具 jmap,jhat及dump分析
  7. 关于 c++ opencv [ INFO:0] global c:\build\master_winpack-build-win64-vc15\***
  8. 映美精双目相机无法同时显示的问题
  9. 腾讯云服务器安全组8080端口开放教程
  10. 中集飞瞳多式联运智能化方案海铁运输数字化集装箱管理,多式联运智能化铁路智能多式联运,中集集团高科技中集飞瞳多式联运智能化领军者
  11. 微信读书vscode插件_曾经我以为 VSCode 是程序员专属的工具,直到发现了这些……...
  12. java中不等于空怎么写_JAVA判断不等于空的情况
  13. 基于Python爬取福建省莆田市天气预报数据获取与预处理的设计与实现
  14. 智学.com查成绩 html,智学.com查分数
  15. 解决div浮动过后 里面元素如何浮动
  16. 华为OD机试Golang解题 - 机器人走迷宫
  17. wp模拟器启动 提示需要 开启硬件辅助虚拟化
  18. 为什么计算机无法读取u盘,为什么usb连接电脑读不出u盘呢?
  19. LMT70驱动—stm32f4
  20. 爬坑 Android Studio 利用Android WIFI ADB 插件实现真机无线调试

热门文章

  1. linux配置内存buffer,Linux中内存buffer和cache的区别
  2. app屡次停止运行怎么解决_打桩机发动机温度过热的问题及运行中熄火怎么解决_行业新闻...
  3. 下拉默认选择_在Excel中制作二级联动下拉菜单,太有用了
  4. tipask二次开发总结_二次开发自我总结
  5. UI实用素材|登录和个人资料界面模板
  6. 设计师必备各类型3D字体图层样式PSD素材
  7. 浪漫七夕节丨中国情人节营销海报模板
  8. Maple: 多项式相乘
  9. 进程(Process)和线程(Thread)的区别
  10. rpm-tree源码分析一波