上一篇章简介了 tensorflow 的程序码,同时也留下了几个後续思考的问题。
这边就以同样是 mnist 的资料集 fashion 来展开讨论。
# Datasets
import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
# Feature Engineering
x_train_n, x_test_n = x_train / 255.0, x_test / 255.0
# Model
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Training model
his = model.fit(x_train_n, y_train, epochs=5, validation_split=0.2, steps_per_epoch=800)
# Score model
score = model.evaluate(x_test, y_test)
score
>> [54.680458068847656, 0.8521999716758728]
我们可以透过 mdoel_load.summary() 指令来获得参数量。
mdoel.summary()
>> Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_1 (Flatten) (None, 784) 0
_________________________________________________________________
dense_2 (Dense) (None, 128) 100480
_________________________________________________________________
dropout_1 (Dropout) (None, 128) 0
_________________________________________________________________
dense_3 (Dense) (None, 10) 1290
=================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
_________________________________________________________________
最後一层的 input 是 128 个权重,那麽我们可以把其一的回归线写作:
总共有 128 个权重 W 与 1 个偏差项 b,共 129 个参数。
再来, output 共输出了 10 条回归线,故总参数量就是 129*10 = 1290!
以 GPT-3(一种自回归语言模型)来说,含有高达 1750 亿个参数呢!
要查看哪些品项容易误判,这时候我们就可利用先前说过的混淆矩阵来帮忙了。
# 如何画出「好看的」混淆矩阵
import sklearn.metrics as skm
import numpy as np
pre = np.argmax(mdoel_load.predict(x_test_n), axis=1) # 预测资料,并且每一列取最大值(最有可能)
cm = skm.confusion_matrix(y_true=y_test, y_pred=pre)
# 用 seaborn 画
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(10, 6))
labels=np.arange(10)
sns.heatmap(
cm, xticklabels=labels, yticklabels=labels,
annot=True, linewidths=0.1, fmt='d', cmap='YlGnBu')
plt.title('Confusion Matrix', fontsize=15)
plt.ylabel('Actual label')
plt.xlabel('Predict label')
这样一来,很清楚可以看到
我们可以参考Keras 官网:
在前篇我们已经有讨论过,依照现有的研究指出,ReLU(可接受 0)及 LeakyReLU(不可接受 0)在大部分情况下效果会最好。
其他还有像是早期使用的 Sigmoid、tanh,以及专门用来归一化的 softmax...等。
更多激励函数可参考维基百科
比起以往的演算法,神经网路特徵更多,以数字辨识为例,就有 28*28 = 784 个特徵。
过多的特徵将导致 overfitting 的问题,因此会在神经层中加入 penalty 惩罚项,以简化 Loss function。
让新的损失函数会变成如下:
其中,我们最常使用的就是 L1 penalty & L2 penalty。
数学上来看,L1 就是直接删去较高的权重,只针对较小的权重寻找最小的损失函数。
而不同於 L1,L2 不使任何权重归零,但会将所有的权重调整,以达到简化模型的目的。
Dropout 层就是随机将特定比例的资料抛弃,以达到矫正 overfitting 简化模型的目的。
基本上可以将每一层 Dense 後方都设定一层 Dropout 层。
至於 Dropout 的比例如何拿捏...那就是黑箱科学的部分了 XD!
要根据经验,资料类型及属性等去判断,并没有一定的比例是最好的~
可以参考Keras 官网中其他的损失函数。
我们目前有接触到的两样如下:
然而,直接将上面的程序码直接改成 MSE 会发现:
# Model
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='mse',
metrics=['accuracy'])
# Training model
his = model.fit(x_train_n, y_train, epochs=5, validation_split=0.2, steps_per_epoch=800)
# Score model
score = model.evaluate(x_test, y_test)
score
>> [27.61042594909668, 0.10019999742507935]
其实,这是因原本损失函数 "sparse_categorical_crossentropy" 里,偷偷包含了一个 sparse categorical。
这个所谓的「稀疏分类」,其实就是我们熟知的「One-hot encoding」。
简单地说,若分类结果有 10 种,他会将 y 自动拆分成 10 个栏位,
若某一样的预测结果是「9」,那麽在「0~8」栏位里面都会是 False,而第 9 栏位是 True。
然而 MSE 的损失函数运算并没有这个功能,因此我们必须手动作业:
# Datasets
import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train_n, x_test_n = x_train / 255.0, x_test / 255.0
# One-hot encoding
y_train = tf.keras.utils.to_categorical(y_train)
y_train[0:1]
>> array([9], dtype=uint8)
查看一下是不是有成功
y_train[0:1]
>> array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]], dtype=float32)
接着 Training,就可以发现准确率回到了原先的 87% 罗!
*注记: One-hot encoding 又分 Ordinal(有序,有大小顺序之分)与 Nominal(名目,仅有 True/False 之分)
.
.
.
.
.
请使用以下网站的资料(日文辨识),作为机器学习的对象。
将四个档案下载完成後,机器学习程序码如下:
import numpy as np
filename = './k49-train-imgs.npz'
arr = np.load(filename)
X_train = arr['arr_0']
filename = './k49-test-imgs.npz'
arr = np.load(filename)
X_test = arr['arr_0']
filename = './k49-train-labels.npz'
arr = np.load(filename)
y_train = arr['arr_0']
filename = './k49-test-labels.npz'
arr = np.load(filename)
y_test = arr['arr_0']
X_train.shape, X_test.shape, y_train.shape, y_test.shape
>> ((232365, 28, 28), (38547, 28, 28), (232365,), (38547,))
*随意取出一笔资料图片:
import matplotlib.pyplot as plt
data_one = X_train[1]
plt.imshow(data_one.reshape(28, 28), cmap='gray')
plt.axis('off')
plt.savefig('tf Japan 01')
plt.show()
看起来是日文字"と(To)"
X_train_n, X_test_n = X_train / 255.0, X_test / 255.0
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(49, activation='softmax')
])
# 选用优化器(此处选择 'adam')
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_train_n, y_train, epochs=5, validation_split=0.2)
score = model.evaluate(X_test_n, y_test)
print(score)
>> [0.9463422894477844, 0.7574648857116699]
import numpy as np
pre = np.argmax(model.predict(X_test_n), axis=1) # 预测资料,每一列取最大值(最有可能的数字)
print("Predict:", pre[0:20])
print("Actual:", y_test[0:20])
>> Predict: [19 4 10 3 26 12 25 9 24 8 19 5 12 46 28 4 9 10 7 13]
Actual: [19 23 10 31 26 12 24 9 24 8 19 5 12 46 28 4 9 10 18 13]
调出第 4 笔错误图片
X_3 = X_test_n[3,:,:]
plt.imshow(X_3.reshape(28,28), cmap='gray')
plt.axis('off')
plt.savefig('tf Japan test 03')
plt.show()
预测为"え(E)",实际上是"み(Mi)"
结论:看来预测文字的精准度远远不及预测数字呢...
上一次介绍完了介面,今天就要来说说实作的部分了,从这里开始我要采取一种“小步快跑”的方式,原本 Ed...
GitHub Repo https://github.com/b2etw/Spring-Kotlin...
各位先进好 如果网域中所有DC作业系统皆为Windows Server 2012 R2 standa...
前言 延续前篇Android Curv Gradient 曲线渐层 过了一个月...终於改好啦!!!...
刚开始学习JavaScript的时候,很单纯的认为所有程序码是逐行执行的,就像看书不都是ㄧ行一行阅读...