識(shí)別鳶尾花(iris)數(shù)據(jù)集
不用keras
無(wú)中間層,最簡(jiǎn)單一層實(shí)現(xiàn)識(shí)別,W個(gè)數(shù)為4*3,b個(gè)數(shù)為3,batch_size為32
# 利用鳶尾花數(shù)據(jù)集,實(shí)現(xiàn)前向傳播、反向傳播,可視化loss曲線
# 導(dǎo)入所需模塊
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np
# 導(dǎo)入數(shù)據(jù),分別為輸入特征和標(biāo)簽
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target
# 隨機(jī)打亂數(shù)據(jù)(因?yàn)樵紨?shù)據(jù)是順序的,順序不打亂會(huì)影響準(zhǔn)確率)
# seed: 隨機(jī)數(shù)種子,是一個(gè)整數(shù),當(dāng)設(shè)置之后,每次生成的隨機(jī)數(shù)都一樣
np.random.seed(116) # 使用相同的seed,保證輸入特征和標(biāo)簽一一對(duì)應(yīng)
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)
# 將打亂后的數(shù)據(jù)集分割為訓(xùn)練集和測(cè)試集,訓(xùn)練集為前120行,測(cè)試集為后30行
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]
# 轉(zhuǎn)換x的數(shù)據(jù)類(lèi)型,否則后面矩陣相乘時(shí)會(huì)因數(shù)據(jù)類(lèi)型不一致報(bào)錯(cuò)
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)
# from_tensor_slices函數(shù)使輸入特征和標(biāo)簽值一一對(duì)應(yīng)。(把數(shù)據(jù)集分批次,每個(gè)批次batch組數(shù)據(jù))
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
# 生成神經(jīng)網(wǎng)絡(luò)的參數(shù),4個(gè)輸入特征數(shù),輸入層為4個(gè)輸入節(jié)點(diǎn);因?yàn)?分類(lèi),故輸出層為3個(gè)神經(jīng)元
# 用tf.Variable()標(biāo)記參數(shù)可訓(xùn)練
# 使用seed使每次生成的隨機(jī)數(shù)相同
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))
lr = 0.1 # 學(xué)習(xí)率為0.1
train_loss_results = [] # 將每輪的loss記錄在此列表中,為后續(xù)畫(huà)loss曲線提供數(shù)據(jù)
test_acc = [] # 將每輪的acc記錄在此列表中,為后續(xù)畫(huà)acc曲線提供數(shù)據(jù)
epoch = 500 # 循環(huán)500輪
loss_all = 0 # 每輪分4個(gè)step,loss_all記錄四個(gè)step生成的4個(gè)loss的和
# 訓(xùn)練部分
for epoch in range(epoch): #數(shù)據(jù)集級(jí)別的循環(huán),每個(gè)epoch循環(huán)一次數(shù)據(jù)集
for step, (x_train, y_train) in enumerate(train_db): #batch級(jí)別的循環(huán) ,每個(gè)step循環(huán)一個(gè)batch
with tf.GradientTape() as tape: # with結(jié)構(gòu)記錄梯度信息
y = tf.matmul(x_train, w1) + b1 # 神經(jīng)網(wǎng)絡(luò)乘加運(yùn)算
y = tf.nn.softmax(y) # 使輸出y符合概率分布(此操作后與獨(dú)熱碼同量級(jí),可相減求loss)
y_ = tf.one_hot(y_train, depth=3) # 將標(biāo)簽值轉(zhuǎn)換為獨(dú)熱碼格式,方便計(jì)算loss和accuracy
loss = tf.reduce_mean(tf.square(y_ - y)) # 采用均方誤差損失函數(shù)mse = mean(sum(y-out)^2)
loss_all += loss.numpy() # 將每個(gè)step計(jì)算出的loss累加,為后續(xù)求loss平均值提供數(shù)據(jù),這樣計(jì)算的loss更準(zhǔn)確
# 計(jì)算loss對(duì)各個(gè)參數(shù)的梯度
grads = tape.gradient(loss, [w1, b1])
# 實(shí)現(xiàn)梯度更新 w1 = w1 - lr * w1_grad b = b - lr * b_grad
w1.assign_sub(lr * grads[0]) # 參數(shù)w1自更新
b1.assign_sub(lr * grads[1]) # 參數(shù)b自更新
# 每個(gè)epoch,打印loss信息
print("Epoch {}, loss: {}".format(epoch, loss_all/4))
train_loss_results.append(loss_all / 4) # 將4個(gè)step的loss求平均記錄在此變量中
loss_all = 0 # loss_all歸零,為記錄下一個(gè)epoch的loss做準(zhǔn)備
# 測(cè)試部分
# total_correct為預(yù)測(cè)對(duì)的樣本個(gè)數(shù), total_number為測(cè)試的總樣本數(shù),將這兩個(gè)變量都初始化為0
total_correct, total_number = 0, 0
for x_test, y_test in test_db:
# 使用更新后的參數(shù)進(jìn)行預(yù)測(cè)
y = tf.matmul(x_test, w1) + b1
y = tf.nn.softmax(y)
pred = tf.argmax(y, axis=1) # 返回y中最大值的索引,即預(yù)測(cè)的分類(lèi)
# 將pred轉(zhuǎn)換為y_test的數(shù)據(jù)類(lèi)型
pred = tf.cast(pred, dtype=y_test.dtype)
# 若分類(lèi)正確,則correct=1,否則為0,將bool型的結(jié)果轉(zhuǎn)換為int型
correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
# 將每個(gè)batch的correct數(shù)加起來(lái)
correct = tf.reduce_sum(correct)
# 將所有batch中的correct數(shù)加起來(lái)
total_correct += int(correct)
# total_number為測(cè)試的總樣本數(shù),也就是x_test的行數(shù),shape[0]返回變量的行數(shù)
total_number += x_test.shape[0]
# 總的準(zhǔn)確率等于total_correct/total_number
acc = total_correct / total_number
test_acc.append(acc)
print("Test_acc:", acc)
print("--------------------------")
# 繪制 loss 曲線
plt.title('Loss Function Curve') # 圖片標(biāo)題
plt.xlabel('Epoch') # x軸變量名稱(chēng)
plt.ylabel('Loss') # y軸變量名稱(chēng)
plt.plot(train_loss_results, label="$Loss$") # 逐點(diǎn)畫(huà)出trian_loss_results值并連線,連線圖標(biāo)是Loss
plt.legend() # 畫(huà)出曲線圖標(biāo)
plt.show() # 畫(huà)出圖像
# 繪制 Accuracy 曲線
plt.title('Acc Curve') # 圖片標(biāo)題
plt.xlabel('Epoch') # x軸變量名稱(chēng)
plt.ylabel('Acc') # y軸變量名稱(chēng)
plt.plot(test_acc, label="$Accuracy$") # 逐點(diǎn)畫(huà)出test_acc值并連線,連線圖標(biāo)是Accuracy
plt.legend()
plt.show()
用keras
import tensorflow as tf
from sklearn import datasets
import numpy as np
#拿到數(shù)據(jù)
x_train = datasets.load_iris().data
y_train = datasets.load_iris().target
#數(shù)據(jù)打亂
np.random.seed(116)
np.random.shuffle(x_train)
np.random.seed(116)
np.random.shuffle(y_train)
tf.random.set_seed(116)
#搭建模型
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())
])
#模型設(shè)置
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
#模型訓(xùn)練
model.fit(x_train, y_train, batch_size=32, epochs=600, validation_split=0.2, validation_freq=20)
model.summary()
識(shí)別MNIST手寫(xiě)數(shù)據(jù)集
不用keras
無(wú)中間層,最簡(jiǎn)單一層實(shí)現(xiàn)識(shí)別,W個(gè)數(shù)為784*10,b個(gè)數(shù)為10,batch_size為512
# -*- coding: UTF-8 -*-
# 利用鳶尾花數(shù)據(jù)集,實(shí)現(xiàn)前向傳播、反向傳播,可視化loss曲線
# 導(dǎo)入所需模塊
import tensorflow as tf
from matplotlib import pyplot as plt
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape(-1,784) # flatten, (60000,28,28)變(60000,784)
x_test = x_test.reshape(-1,784) # flatten, (10000,28,28)變(10000,784)
# 轉(zhuǎn)換x的數(shù)據(jù)類(lèi)型,否則后面矩陣相乘時(shí)會(huì)因數(shù)據(jù)類(lèi)型不一致報(bào)錯(cuò)
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)
# from_tensor_slices函數(shù)使輸入特征和標(biāo)簽值一一對(duì)應(yīng)。(把數(shù)據(jù)集分批次,每個(gè)批次batch組數(shù)據(jù))
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(512)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(512)
# 生成神經(jīng)網(wǎng)絡(luò)的參數(shù),4個(gè)輸入特征故,輸入層為4個(gè)輸入節(jié)點(diǎn);因?yàn)?分類(lèi),故輸出層為3個(gè)神經(jīng)元
# 用tf.Variable()標(biāo)記參數(shù)可訓(xùn)練
# 使用seed使每次生成的隨機(jī)數(shù)相同(方便教學(xué),使大家結(jié)果都一致,在現(xiàn)實(shí)使用時(shí)不寫(xiě)seed)
w1 = tf.Variable(tf.random.truncated_normal([784, 10], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([10], stddev=0.1, seed=1))
lr = 0.05 # 學(xué)習(xí)率為0.1
train_loss_results = [] # 將每輪的loss記錄在此列表中,為后續(xù)畫(huà)loss曲線提供數(shù)據(jù)
test_acc = [] # 將每輪的acc記錄在此列表中,為后續(xù)畫(huà)acc曲線提供數(shù)據(jù)
epoch = 500 # 循環(huán)500輪
loss_all = 0 # 每輪分4個(gè)step,loss_all記錄四個(gè)step生成的4個(gè)loss的和
# 訓(xùn)練部分
for epoch in range(epoch): #數(shù)據(jù)集級(jí)別的循環(huán),每個(gè)epoch循環(huán)一次數(shù)據(jù)集
for step, (x_train, y_train) in enumerate(train_db): #batch級(jí)別的循環(huán) ,每個(gè)step循環(huán)一個(gè)batch
with tf.GradientTape() as tape: # with結(jié)構(gòu)記錄梯度信息
y = tf.matmul(x_train, w1) + b1 # 神經(jīng)網(wǎng)絡(luò)乘加運(yùn)算
y = tf.nn.softmax(y) # 使輸出y符合概率分布(此操作后與獨(dú)熱碼同量級(jí),可相減求loss)
y_ = tf.one_hot(y_train, depth=10) # 將標(biāo)簽值轉(zhuǎn)換為獨(dú)熱碼格式,方便計(jì)算loss和accuracy
loss = tf.reduce_mean(tf.square(y_ - y)) # 采用均方誤差損失函數(shù)mse = mean(sum(y-out)^2)
loss_all += loss.numpy() # 將每個(gè)step計(jì)算出的loss累加,為后續(xù)求loss平均值提供數(shù)據(jù),這樣計(jì)算的loss更準(zhǔn)確
# 計(jì)算loss對(duì)各個(gè)參數(shù)的梯度
grads = tape.gradient(loss, [w1, b1])
# 實(shí)現(xiàn)梯度更新 w1 = w1 - lr * w1_grad b = b - lr * b_grad
w1.assign_sub(lr * grads[0]) # 參數(shù)w1自更新
b1.assign_sub(lr * grads[1]) # 參數(shù)b自更新
# 每個(gè)epoch,打印loss信息
print("Epoch {}, loss: {}".format(epoch, loss_all/118))
train_loss_results.append(loss_all / 118) # 將4個(gè)step的loss求平均記錄在此變量中
loss_all = 0 # loss_all歸零,為記錄下一個(gè)epoch的loss做準(zhǔn)備
# 測(cè)試部分
# total_correct為預(yù)測(cè)對(duì)的樣本個(gè)數(shù), total_number為測(cè)試的總樣本數(shù),將這兩個(gè)變量都初始化為0
total_correct, total_number = 0, 0
for x_test, y_test in test_db:
# 使用更新后的參數(shù)進(jìn)行預(yù)測(cè)
y = tf.matmul(x_test, w1) + b1
y = tf.nn.softmax(y)
pred = tf.argmax(y, axis=1) # 返回y中最大值的索引,即預(yù)測(cè)的分類(lèi)
# 將pred轉(zhuǎn)換為y_test的數(shù)據(jù)類(lèi)型
pred = tf.cast(pred, dtype=y_test.dtype)
# 若分類(lèi)正確,則correct=1,否則為0,將bool型的結(jié)果轉(zhuǎn)換為int型
correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
# 將每個(gè)batch的correct數(shù)加起來(lái)
correct = tf.reduce_sum(correct)
# 將所有batch中的correct數(shù)加起來(lái)
total_correct += int(correct)
# total_number為測(cè)試的總樣本數(shù),也就是x_test的行數(shù),shape[0]返回變量的行數(shù)
total_number += x_test.shape[0]
# 總的準(zhǔn)確率等于total_correct/total_number
acc = total_correct / total_number
test_acc.append(acc)
print("Test_acc:", acc)
print("--------------------------")
# 繪制 loss 曲線
plt.subplot(1,2,1)
plt.title('Loss Function Curve') # 圖片標(biāo)題
plt.xlabel('Epoch') # x軸變量名稱(chēng)
plt.ylabel('Loss') # y軸變量名稱(chēng)
plt.plot(train_loss_results, label="$Loss$") # 逐點(diǎn)畫(huà)出trian_loss_results值并連線,連線圖標(biāo)是Loss
plt.legend() # 畫(huà)出曲線圖標(biāo)
# 繪制 Accuracy 曲線
plt.subplot(1,2,2)
plt.title('Acc Curve') # 圖片標(biāo)題
plt.xlabel('Epoch') # x軸變量名稱(chēng)
plt.ylabel('Acc') # y軸變量名稱(chēng)
plt.plot(test_acc, label="$Accuracy$") # 逐點(diǎn)畫(huà)出test_acc值并連線,連線圖標(biāo)是Accuracy
plt.legend()
plt.show()
用keras
2層中間層(flatten層算輸入層),W個(gè)數(shù)為784128+12810,b個(gè)數(shù)為128+10
import tensorflow as tf
#拿到數(shù)據(jù)
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
#搭建模型
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
#模型設(shè)置
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
#模型訓(xùn)練
model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1)
model.summary()
閱讀全文