《机器学习实战:基于Scikit-Learn、Keras和TensorFlow(第二版)》第10章 使用Keras搭建人工神经网络·精华代码

电脑上看效果好,不用左右滑屏。都调好了,复制粘贴就可以在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])


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249