python深度学习——案例讲解

python深度学习——知识总结与整理

知识点1:基于keras的手写数字识别
最近在看基于python的深度学习,首先是一个入门程序,基于keras框架的手写数字识别。手写数字的数据集由60000张训练数据和10000张测试数据组成。这些数据都是一个由8位整数组成的3D张量(当然要想查看数据的属性,可以使用shape/ndim/dtype等属性查看),更确切地说,它是60000个矩阵组成的数组,每个矩阵由28*28个整数组成,每个这样的矩阵都是一个灰度图像,在灰度图像中每一个元素的取值范围都是0~255。
本文采用两层全连接神经网络进行训练,由训练结果可以看到,训练数据集的准确率是98.89%,而测试数据集的准确率是98.1%,这是因为训练时的过拟合造成的,这在之后的博文中会详细分析。
在这里插入图片描述
代码如下,python3.7.3,IDE是pycharm专业版

'''
@author: liuyunsheng
@file: handwriting.py
@time: 2019/5/16 19:49
@desc:
'''
from keras import models
import matplotlib.pyplot as plt
from keras import layers
from keras.utils import to_categorical
# 提取数据
from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 当然你也可以用matplotlib库来显示每一个数据
digit = train_images[4]
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
# 搭建神经网络;神经网络的核心组件是层(layer),可以看做是进去一些数据,出来的数据更加有用
# 下面的神经网络包含两个层,两个全连接层,第二个是一个softmax层,将会返回一个由10个概率值组成的数组
# 每个概率表示当前数字图像属于10个数字类别中某一个的概率
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
# 编译,选择损失函数,优化器和训练以及测试过程中需要监控的指标,本案例只关注精度,即正确分类的图像所占的比例
network.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
# 训练之前,需要对数据进行预处理,将其变换为网络要求的形状,并缩放到所有值都在[0,1]之间
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
# 还需要对标签进行分类编码
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# 训练网络,调用fit方法
network.fit(train_images, train_labels, epochs=5, batch_size=128)
# 检查模型在测试集的性能
test_loss, test_acc = network.evaluate(test_images, test_labels)
print(test_acc)

使用matplotlib显示其中一个数据:
在这里插入图片描述
知识点2:张量运算
张量其实并不是一个陌生的概念,我们可以将张量理解为矩阵向任意维度的推广。
1、张量的分类(0维张量(标量)、1维张量(向量)、2维张量(矩阵)、3维张量(空间排列的矩阵))
2、张量的关键属性(轴的个数–阶,形状,数据类型)
3、操作张量:即从数组中取值
4、数据批量的概念:一般地,深度学习中所有数据张量的第一个轴都是样本轴,深度学习模型不会同时处理所有的数据,而是将数据拆分成小批量,因此将数据集的第一个轴称为批量轴或批量维度
5、张量逐元素运算、广播、张量点积、张量变形都是Python中对数据的基本操作

知识点3:电影评论划分
习惯性,先上结论,有个清晰的认知:
在这里插入图片描述
问题描述:这个案例使用的是IMDB即互联网电影数据库中的50000条两级分化的电影评论,其中25000条用于训练,25000条用于测试,每个数据集中都包含50%的正面和负面评论
上代码:

'''
@author: liuyunsheng
@file: InternetMoviesDatabase.py
@time: 2019/5/17 9:02
@desc:
'''
from keras.datasets import imdb
import numpy as np
from keras import models
from keras import layers
import matplotlib.pyplot as plt
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
# 1、加载数据集(num_words=10000表示仅保留训练中前10000个最常出现的单词)
# 值得注意的是这些数据是经过预处理的,即每条评论都是由单词索引组成的列表,可以通过train_data[0]等查看
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
# 将索引的单词列表转化成英文单词
word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
# 2、准备数据,对列表进行one-hot编码,将其转换为01组成的向量;以及将标签向量化
def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

# 3、构建网络
# 3.1确定网络需要多少层、每层需要多少隐藏单元
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
# 3.2选择损失函数和优化器
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
# 4、为了在训练过程中监控模型在未知数据上的精度,需要将原始训练数据留出10000个样本作为验证集
x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]
# 5、训练模型
history = model.fit(partial_x_train,partial_y_train,epochs=20,batch_size=512,validation_data=(x_val, y_val))
# 6、绘制训练损失和验证损失
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='训练损失')
plt.plot(epochs, val_loss_values, 'b', label='验证损失')
plt.title('训练和验证损失')
plt.xlabel('步长')
plt.ylabel('损失')
plt.legend()
plt.show()

知识点4:新闻类别判定

问题:对路透社的新闻数据集进行划分,每个新闻都只有一个标签,但是一共有46个互斥的类别
习惯性的先上结果图,分别是训练精度和验证精度、训练损失和验证损失:
在这里插入图片描述
在这里插入图片描述

代码:

'''
@author: liuyunsheng
@file: news.py
@time: 2019/5/17 10:39
@desc: 
'''
from keras.datasets import reuters
import numpy as np
from keras import models
from keras import layers
import matplotlib.pyplot as plt
# 控制中文显示
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
from keras.utils.np_utils import to_categorical
# 加载数据
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)
# 将数据解析成英文单词
word_index = reuters.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_newswire = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
# 将数据向量化
def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
# 将标签向量化,方法1:自己写函数实现
# 方法2:当然也可以是用keras内置函数实现操作
# one_hot_train_labels = to_categorical(train_labels)
# one_hot_test_labels = to_categorical(test_labels)
def to_one_hot(labels, dimension=46):
    results = np.zeros((len(labels), dimension))
    for i, label in enumerate(labels):
        results[i, label] = 1.
    return results
one_hot_train_labels = to_one_hot(train_labels)
one_hot_test_labels = to_one_hot(test_labels)
# 构建网络:值得注意的是网络最后一层是大小为46的全连接层,会输出一个46维的向量,每个元素代表不同的输出类别
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
# 编译模型
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
# 留出验证集
x_val = x_train[:1000]
partial_x_train = x_train[1000:]
y_val = one_hot_train_labels[:1000]
partial_y_train = one_hot_train_labels[1000:]
# 训练模型
history = model.fit(partial_x_train,partial_y_train,epochs=20,batch_size=512,validation_data=(x_val, y_val))
# 绘制训练损失和验证损失
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(loss) + 1)
plt.plot(epochs, loss, 'bo', label='训练损失')
plt.plot(epochs, val_loss, 'b', label='验证损失')
plt.title('训练损失和验证损失')
plt.xlabel('步长')
plt.ylabel('损失')
plt.legend()
plt.show()
# 绘制训练精度和验证精度
plt.clf()
acc = history.history['acc']
val_acc = history.history['val_acc']
plt.plot(epochs, acc, 'bo', label='训练精度')
plt.plot(epochs, val_acc, 'b', label='验证精度')
plt.title('训练精度和验证精度')
plt.xlabel('步长')
plt.ylabel('精度')
plt.legend()
plt.show()

知识点5:波士顿房价预测

问题描述:预测20 世纪70 年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。BostonHousing的数据点相对较少,只有506个,分为404个训练样本和102个测试样本,输入数据的每个特征(比如犯罪率)都有不同的取值范围。
预测结果:
在这里插入图片描述
代码:

'''
@author: liuyunsheng
@file: BostonHousing.py
@time: 2019/5/17 12:34
@desc: 
'''
from keras.datasets import boston_housing
from keras import models
from keras import layers
import numpy as np
import matplotlib.pyplot as plt
# 加载数据
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
# 数据标准化,值得注意的是这里用于测试的数据标准化的均值和标准差也是在训练数据集上面得到的
mean = train_data.mean(axis=0)
train_data -= mean
std = train_data.std(axis=0)
train_data /= std
test_data -= mean
test_data /= std
# 构建网络
def build_model():
    model = models.Sequential()
    model.add(layers.Dense(64, activation='relu',
    input_shape=(train_data.shape[1],)))
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.Dense(1))
    model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
    return model
k = 4
num_val_samples = len(train_data) // k
num_epochs = 100
all_scores = []
# 由于数据比较少,因此这里采用K折交叉验证,即将数据划分为K个分区,通常为4或5
# 实例化K个相同的模型,将每个模型在K-1个分区上训练,在剩下一个分区进行评估
# 模型的验证分数等于K个验证分数的平均值
num_epochs = 500
all_mae_histories = []
for i in range(k):
    print('processing fold #', i)
    val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples]
    val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]
    partial_train_data = np.concatenate(
        [train_data[:i * num_val_samples],
         train_data[(i + 1) * num_val_samples:]],
        axis=0)
    partial_train_targets = np.concatenate(
        [train_targets[:i * num_val_samples],
         train_targets[(i + 1) * num_val_samples:]],
        axis=0)
    model = build_model()
    history = model.fit(partial_train_data, partial_train_targets,
                        validation_data=(val_data, val_targets),
                        epochs=num_epochs, batch_size=1, verbose=0)
    mae_history = history.history['val_mean_absolute_error']
    all_mae_histories.append(mae_history)
average_mae_history = [np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)]
# 绘制验证分数
plt.plot(range(1, len(average_mae_history) + 1), average_mae_history)
plt.xlabel('步长')
plt.ylabel('验证的平均绝对误差MAE')
plt.show()
  • 16
    点赞
  • 231
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值