首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第10章 使用Keras搭建人工神经网络·精华代码

第10章 使用Keras搭建人工神经网络·精华代码

作者头像
SeanCheney
发布2019-10-21 17:15:06
1.2K0
发布2019-10-21 17:15:06
举报
文章被收录于专栏:SeanCheney的专栏SeanCheney的专栏

电脑上看效果好,不用左右滑屏。都调好了,复制粘贴就可以在PyCharm里直接跑起来。

# -*- coding: utf-8 -*-

# 需要安装和引入的包有tensorflow\pandas\numpy\matplotlib\scikit-learn
# 使用pip安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ tensorflow pandas matplotlib scikit-learn

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tensorflow import keras

# 加载Fashion MNIST数据集,格式与MNIST完全相同(70000张灰度图,每张的像素是28 × 28,
# 共有10类),图的内容是流行物品,每类中的图片更丰富,# 识图的挑战性比MNIST高得多。
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()

# 训练集的形状和类型
print('训练集的形状:60000张图片,像素是28×28', X_train_full.shape)
print('训练集的数据类型', X_train_full.dtype)

# 该数据集已经分成了训练集和测试集,但没有验证集。所以要建一个验证集,另外,因为要用梯度下
# 降训练神经网络,必须要对输入特征进行缩放。简单起见,通过除以255.0将强度范围变为0-1:
X_valid, X_train = X_train_full[:5000] / 255.0, X_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]

# Fashion MNIST的分类名列表:
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
               "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]

# 训练集的第一个y值是4,所以属于Coat
print('训练集的第一个y值是4,所以属于:', class_names[y_train[0]])


# 创建一个Sequential模型,这是Keras最简单的模型,是由单层神经元顺序连起来的,被称为Sequential API
model = keras.models.Sequential()
# 接下来创建了第一层,这是一个Flatten层,它的作用是将每个输入图片转变为1D数组:如果输入数据是矩阵X,
# 该层则计算X.reshape(-1, 1)。该层没有任何参数,只是做一些简单预处理。因为是模型的第一层,必须要指
# 明input_shape,input_shape不包括批次大小,只是实例的形状。
model.add(keras.layers.Flatten(input_shape=[28, 28]))
# 添加一个有300个神经元的紧密层,激活函数是ReLU。每个紧密层只负责自身的权重矩阵,权重矩阵是神经元与输
# 入的所有连接权重。紧密层还要负责偏置项
# (每个神经元都有一个偏置项)矢量。
model.add(keras.layers.Dense(300, activation="relu"))
# 再添加第二个紧密层,激活函数仍然是ReLU
model.add(keras.layers.Dense(100, activation="relu"))
# 最后,加上一个拥有10个神经元的输出层(每有一个类就要有一个神经元),激活函数是softmax(保证输出的
# 概率和等于1,因为就只有这十个类,具有排他性)
model.add(keras.layers.Dense(10, activation="softmax"))

# 除了一层一层加层,也可以传递一个层组成的列表:
# model = keras.models.Sequential([
#     keras.layers.Flatten(input_shape=[28, 28]),
#     keras.layers.Dense(300, activation="relu"),
#     keras.layers.Dense(100, activation="relu"),
#     keras.layers.Dense(10, activation="softmax")
# ])

# 模型的summary()方法可以展示所有层,包括每个层的名字(名字是自动生成的,除非建层时指定名字),输出
# 的形状(None代表批次大小可以是任意值),和参数的数量。
print(model.summary())

# 获取所有的层
print(model.layers)

# 每个层的名字
print([layer.name for layer in model.layers])

# 可以用get_weights()和set_weights()方法,获取神经层的所有参数。对于紧密层,参数包括连接权重和
# 偏置项:
hidden1 = model.layers[1]
weights, biases = hidden1.get_weights()
print(weights)
print(weights.shape)
print(biases)
print(biases.shape)


# 编译模型
# 首先,因为使用的是稀疏标签(每个实例只有一个目标类的索引,在这个例子中,目标类索引是0到9),且就
# 是这十个类,没有其它的,所以使用的是"sparse_categorical_crossentropy"损失函数。如果每个实例
# 的每个类都有一个目标概率(比如独热矢量,[0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],来表示类3),
# 则就要使用"categorical_crossentropy"损失函数。如果是做二元分类(有一个或多个二元标签),输出层
# 就得使用"sigmoid"激活函数,损失函数则变为"binary_crossentropy"。对于优化器,"sgd"表示使用随机
# 梯度下降训练模型。换句话说,Keras会进行反向传播算法。最后,因为是个分类器,最好在训练和评估时测量
# "accuracy"。
model.compile(loss="sparse_categorical_crossentropy",
              optimizer="sgd",
              metrics=["accuracy"])

# 训练模型
# 向fit()方法传递了输入特征(X_train)和目标类(y_train),还要要训练的周期数(不设置的话,默认的周期
# 数是1,肯定是不能收敛到一个好的解的)。另外还传递了验证集(它是可选的)。Keras会在每个周期结束后,
# 测量损失和指标,这样就可以监测模型的表现。如果模型在训练集上的表现优于在验证集上的表现,可能模型在训
# 练集上就过拟合了(或者就是存在bug,比如训练集和验证集的数据不匹配)。为节省时间,周期数设成10
history = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))


# 画学习曲线
# fit()方法会返回History对象,包含:训练参数(history.params)、周期列表(history.epoch)、以及
# 最重要的包含训练集和验证集的每个周期后的损失和指标的字典(history.history)。如果用这个字典创建一个
# pandas的DataFrame,然后使用方法plot(),就可以画出学习曲线
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 1) # 纵坐标的范围设为0-1
plt.show()


# 用测试集评估泛化误差。只需使用evaluate()方法
print(model.evaluate(X_test, y_test))


# 使用模型进行预测
X_new = X_test[:3]
y_proba = model.predict(X_new)
print(y_proba.round(2))
# 我得到的结果是,输出的是概率值:
# [[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
#  [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
#  [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]

# 输出的是类别名
y_pred = model.predict_classes(X_new)
print(np.array(class_names)[y_pred])


# 使用Sequential API搭建回归MLP
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 获取数据
housing = fetch_california_housing()

# 切分数据集
X_train_full, X_test, y_train_full, y_test = train_test_split(
    housing.data, housing.target)
X_train, X_valid, y_train, y_valid = train_test_split(
    X_train_full, y_train_full)

# 做特征缩放
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_valid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)

# 使用Sequential API搭建、训练、评估和使用回归MLP做预测,和前面的分类MLP很像。区别在于输出层只有
# 一个神经元(因为只想预测一个值而已),也没有使用激活函数,损失函数是均方误差。因为数据集有噪音,我
# 们就是用一个隐藏层,并且神经元也比之前少,以避免过拟合:
model = keras.models.Sequential([
    keras.layers.Dense(30, activation="relu", input_shape=X_train.shape[1:]),
    keras.layers.Dense(1)
])
# 编译
model.compile(loss="mean_squared_error", optimizer="sgd")
# 训练
history = model.fit(X_train, y_train, epochs=20,
                    validation_data=(X_valid, y_valid))
# 评估
mse_test = model.evaluate(X_test, y_test)
# 预测
X_new = X_test[:3] # pretend these are new instances
y_pred = model.predict(X_new)
print(y_pred)


# 保存模型
# model = keras.layers.Sequential([...]) # or keras.Model([...])
# model.compile([...])
# model.fit([...])
# model.save("my_keras_model.h5")


# 加载模型
# model = keras.models.load_model("my_keras_model.h5")



# 使用调回创建检查点
# fit()方法接受参数callbacks,可以让用户指明一个Keras列表,让Keras在训练开始和结束、每个周期开
# 始和结束、甚至是每个批次的前后调用。例如,ModelCheckpoint可以在每个时间间隔保存检查点,默认是
# 每个周期结束之后:
#  [...] # 搭建编译模型
# checkpoint_cb = keras.callbacks.ModelCheckpoint("my_keras_model.h5")
# history = model.fit(X_train, y_train, epochs=10, callbacks=[checkpoint_cb])

# 早停的两种方法
# 另外,如果训练时使用了验证集,可以在创建检查点时设定save_best_only=True,只有当模型在验证集上
# 取得最优值时才保存模型。这么做可以不必担心训练时间过长和训练集过拟合:只需加载训练好的模型,就能保
# 证是在验证集上表现最好的模型。
# checkpoint_cb = keras.callbacks.ModelCheckpoint("my_keras_model.h5",
#                                                 save_best_only=True)
# history = model.fit(X_train, y_train, epochs=10,
#                     validation_data=(X_valid, y_valid),
#                     callbacks=[checkpoint_cb])
# model = keras.models.load_model("my_keras_model.h5") # 滚回到最优模型

# 另一种实现早停的方法是使用EarlyStopping调回。当检测到经过几个周期(周期数由参数patience确定),
# 验证集表现没有提升时,就会中断训练,还能自动滚回到最优模型。可以将保存检查点(避免宕机)和早停
# (避免浪费时间和资源)结合起来:
# early_stopping_cb = keras.callbacks.EarlyStopping(patience=10,
#                                                   restore_best_weights=True)
# history = model.fit(X_train, y_train, epochs=100,
#                     validation_data=(X_valid, y_valid),
#                     callbacks=[checkpoint_cb, early_stopping_cb])
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.10.17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档