大家好,這篇文章分享了C程式設計(譚浩強)第五版第四章課後題答案,所有程式已經測試能夠正常運行,如果小伙伴發現有錯誤的的地方,歡迎留言告訴我,我會及時改正!感謝大家的觀看!!! ...
引言
TensorFlow提供了多種API,使得入門者和專家可以根據自己的需求選擇不同的API搭建模型。
基於Keras Sequential API搭建模型
Sequential適用於線性堆疊的方式搭建模型,即每層只有一個輸入和輸出。
import tensorflow as tf # 導入手寫數字數據集 mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() # 數據標準化 x_train, x_test = x_train/255, x_test/255 # 使用Sequential搭建模型 # 方式一 model = tf.keras.models.Sequential([ # 加入CNN層(2D), 使用了3個捲積核, 捲積核的尺寸為3X3, 步長為1, 輸入圖像的維度為28X28X1 tf.keras.layers.Conv2D(3, kernel_size=3, strides=1, input_shape=(28, 28, 1)), # 加入激活函數 tf.keras.layers.Activation('relu'), # 加入2X2池化層, 步長為2 tf.keras.layers.MaxPool2D(pool_size=2, strides=2), # 把圖像數據平鋪 tf.keras.layers.Flatten(), # 加入全連接層, 設置神經元為128個, 設置relu激活函數 tf.keras.layers.Dense(128, activation='relu'), # 加入全連接層(輸出層), 設置輸出數量為10, 設置softmax激活函數 tf.keras.layers.Dense(10, activation='softmax') ]) # 方式二 model2 = tf.keras.models.Sequential() model2.add(tf.keras.layers.Conv2D(3, kernel_size=3, strides=1, input_shape=(28, 28, 1))) model2.add(tf.keras.layers.Activation('relu')) model2.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2)) model2.add(tf.keras.layers.Flatten()) model2.add(tf.keras.layers.Dense(128, activation='relu')) model2.add(tf.keras.layers.Dense(10, activation='softmax')) # 模型概覽 model.summary() """ Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 26, 26, 3) 30 activation (Activation) (None, 26, 26, 3) 0 max_pooling2d (MaxPooling2D (None, 13, 13, 3) 0 ) flatten (Flatten) (None, 507) 0 dense (Dense) (None, 128) 65024 dense_1 (Dense) (None, 10) 1290 ================================================================= Total params: 66,344 Trainable params: 66,344 """ # 編譯 為模型加入優化器, 損失函數, 評估指標 model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'] ) # 訓練模型, 2個epoch, batch size為100 model.fit(x_train, y_train, epochs=2, batch_size=100)
基於Keras 函數API搭建模型
由於Sequential是線性堆疊的,只有一個輸入和輸出,但是當我們需要搭建多輸入模型時,如輸入圖片、文本描述等,這幾類信息可能需要分別使用CNN,RNN模型提取信息,然後彙總信息到最後的神經網路中預測輸出。或者是多輸出任務,如根據音樂預測音樂類型和發行時間。亦或是一些非線性的拓撲網路結構模型,如使用殘差鏈接、Inception等。上述這些情況的網路都不是線性搭建,要搭建如此複雜的網路,需要使用函數API來搭建。
簡單實例
import tensorflow as tf # 導入手寫數字數據集 mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() # 數據標準化 x_train, x_test = x_train/255, x_test/255 input_tensor = tf.keras.layers.Input(shape=(28, 28, 1)) # CNN層(2D), 使用了3個捲積核, 捲積核的尺寸為3X3, 步長為1, 輸入圖像的維度為28X28X1 x = tf.keras.layers.Conv2D(3, kernel_size=3, strides=1)(input_tensor) # 激活函數 x = tf.keras.layers.Activation('relu')(x) # 2X2池化層, 步長為2 x = tf.keras.layers.MaxPool2D(pool_size=2, strides=2)(x) # 把圖像數據平鋪 x = tf.keras.layers.Flatten()(x) # 全連接層, 設置神經元為128個, 設置relu激活函數 x = tf.keras.layers.Dense(128, activation='relu')(x) # 全連接層(輸出層), 設置輸出數量為10, 設置softmax激活函數 output = tf.keras.layers.Dense(10, activation='softmax')(x) model = tf.keras.models.Model(input_tensor, output) # 模型概覽 model.summary() """ Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) [(None, 28, 28, 1)] 0 conv2d (Conv2D) (None, 26, 26, 3) 30 activation (Activation) (None, 26, 26, 3) 0 max_pooling2d (MaxPooling2D (None, 13, 13, 3) 0 ) flatten (Flatten) (None, 507) 0 dense (Dense) (None, 128) 65024 dense_1 (Dense) (None, 10) 1290 ================================================================= Total params: 66,344 Trainable params: 66,344 Non-trainable params: 0 _________________________________________________________________ """ # 編譯 為模型加入優化器, 損失函數, 評估指標 model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'] ) # 訓練模型, 2個epoch, batch size為100 model.fit(x_train, y_train, epochs=2, batch_size=100)
多輸入實例
import tensorflow as tf # 輸入1 input_tensor1 = tf.keras.layers.Input(shape=(28,)) x1 = tf.keras.layers.Dense(16, activation='relu')(input_tensor1) output1 = tf.keras.layers.Dense(32, activation='relu')(x1) # 輸入2 input_tensor2 = tf.keras.layers.Input(shape=(28,)) x2 = tf.keras.layers.Dense(16, activation='relu')(input_tensor2) output2 = tf.keras.layers.Dense(32, activation='relu')(x2) # 合併輸入1和輸入2 concat = tf.keras.layers.concatenate([output1, output2]) # 頂層分類模型 output = tf.keras.layers.Dense(10, activation='relu')(concat) model = tf.keras.models.Model([input_tensor1, input_tensor2], output) # 編譯 model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'] )
多輸出實例
import tensorflow as tf # 輸入 input_tensor = tf.keras.layers.Input(shape=(28,)) x = tf.keras.layers.Dense(16, activation='relu')(input_tensor) output = tf.keras.layers.Dense(32, activation='relu')(x) # 多個輸出 output1 = tf.keras.layers.Dense(10, activation='relu')(output) output2 = tf.keras.layers.Dense(1, activation='sigmoid')(output) model = tf.keras.models.Model(input_tensor, [output1, output2]) # 編譯 model.compile( optimizer='adam', loss=['sparse_categorical_crossentropy', 'binary_crossentropy'], metrics=['accuracy'] )
子類化API
相較於上述使用高階API,使用子類化API的方式來搭建模型,可以根據需求對模型中的任何一部分進行修改。
import tensorflow as tf # 導入手寫數字數據集 mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() # 數據標準化 x_train, x_test = x_train / 255, x_test / 255 train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(buffer_size=10).batch(32) test_data = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32) class MyModel(tf.keras.Model): def __init__(self): super(MyModel, self).__init__() self.flatten = tf.keras.layers.Flatten() self.hidden_layer1 = tf.keras.layers.Dense(16, activation='relu') self.hidden_layer2 = tf.keras.layers.Dense(10, activation='softmax') # 定義模型 def call(self, x): h = self.flatten(x) h = self.hidden_layer1(h) y = self.hidden_layer2(h) return y model = MyModel() # 損失函數 和 優化器 loss_function = tf.keras.losses.SparseCategoricalCrossentropy() optimizer = tf.keras.optimizers.Adam() # 評估指標 train_loss = tf.keras.metrics.Mean() # 一個epoch的loss train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy() # 一個epoch的準確率 test_loss = tf.keras.metrics.Mean() test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy() @tf.function def train_step(x, y): with tf.GradientTape() as tape: y_pre = model(x) loss = loss_function(y, y_pre) grad = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(grad, model.trainable_variables)) train_loss(loss) train_accuracy(y, y_pre) @tf.function def test_step(x, y): y_pre = model(x) te_loss = loss_function(y, y_pre) test_loss(te_loss) test_accuracy(y, y_pre) epoch = 2 for i in range(epoch): # 重置評估指標 train_loss.reset_states() train_accuracy.reset_states() # 按照batch size 進行訓練 for x, y in train_data: train_step(x, y) print(f'epoch {i+1} train loss {train_loss.result()} train accuracy {train_accuracy.result()}')
參考
本文來自博客園,作者:LoveFishO,轉載請註明原文鏈接:https://www.cnblogs.com/lovefisho/p/16279836.html