[深度學習][Python]DCGAN訓練生成手寫阿拉伯數字_訓練篇

更新於 發佈於 閱讀時間約 21 分鐘

本文參考TensorFlo官網Deep Convolutional Generative Adversarial Network的程式碼來加以實作說明。

示範如何使用深度卷積生成對抗網路(DCGAN) 生成手寫數位影像。程式碼是使用帶有訓練循環的Keras Sequential APItf.GradientTape編寫的。

使用 MNIST 資料集來訓練生成器和判別器。生成器將生成類似於 MNIST 資料的手寫數字。

動畫顯示

以下動畫顯示了生成器經過 50 個 epoch 訓練後生成的一系列圖像。這些圖像一開始是隨機噪聲,隨著時間的推移越來越像手寫數字。

訓練過程50次的過程

訓練過程50次的過程


本文在Colab上執行訓練,因本機電腦過於老舊XD

Python及套件版本

Python version: 3.10.12
imageio version: 2.34.2
matplotlib version: 3.7.1
numpy version: 1.25.2
PIL version: 9.4.0
tensorflow version: 2.15.0
IPython version: 7.34.0

1.載入相關套件

import glob
import imageio
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tf
from tensorflow.keras import layers
import time
from IPython import display

2. 載入訓練資料

# 取得 MNIST 訓練資料
(train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data()
# 像素標準化
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
train_images = (train_images - 127.5) / 127.5 # 使像素值介於 [-1, 1]

# 參數設定
BUFFER_SIZE = 60000 # 緩衝區大小
BATCH_SIZE = 256 # 訓練批量

# 轉為 Dataset
train_dataset = tf.data.Dataset.from_tensor_slices(train_images) \
.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(BUFFER_SIZE).cache()

3. 定義GAN模型

3.1 定義生成模型

將從一個隨機噪聲向量中生成28x28圖像

# 生成神經網路
def make_generator_model():
model = tf.keras.Sequential()
# 第一層 Dense
#輸入是一個100維的隨機向量,輸出是7x7x256個特徵圖(feature maps)。
model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
#對輸出進行批量標準化(Batch Normalization),有助於穩定和加速訓練過程。
model.add(layers.BatchNormalization())
#應用Leaky ReLU激活函數,這是一種具有輕微負斜率的ReLU激活函數,可以解決ReLU的“死亡神經元”問題
model.add(layers.LeakyReLU())
​​#將輸出重塑為7x7x256的形狀,以便於後續的卷積操作。
model.add(layers.Reshape((7, 7, 256)))
#檢查
assert model.output_shape == (None, 7, 7, 256) # None 代表批量不檢查
# 第一層 Conv2DTranspose​
# 將低分辨率的特徵圖轉換為高分辨率的特徵圖
model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1),
padding='same', use_bias=False))
assert model.output_shape == (None, 7, 7, 128)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
# 第二層 Conv2DTranspose​
model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2),
padding='same', use_bias=False))
assert model.output_shape == (None, 14, 14, 64)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
# 第三層 Conv2DTranspose​
# 將特徵圖尺寸放大到28x28,並使用'tanh'激活函數將輸出範圍限制在[-1, 1]之間。​
model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2),
padding='same', use_bias=False, activation='tanh'))
assert model.output_shape == (None, 28, 28, 1)

return model

顯示生成雜訊

# 產生生成神經網路
generator = make_generator_model()

# 測試產生的雜訊
noise = tf.random.normal([1, 100])
generated_image = generator(noise, training=False)

# 顯示雜訊生成的圖像
plt.imshow(generated_image[0, :, :, 0], cmap='gray')
raw-image

3.2 定義判別器模型

判别器模型在訓練過程中會學習區分真實圖像和生成圖像,並將其用於改進生成器模型,使得生成的圖像越來越真實。

# 判别神經網路
def make_discriminator_model():
model = tf.keras.Sequential() #定義模型:使用tf.keras.Sequential定義了一個順序模型。
model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
input_shape=[28, 28, 1])) #卷積層, 輸入28*28
model.add(layers.LeakyReLU()) #使用Leaky ReLU作為激活函數
model.add(layers.Dropout(0.3)) #應用Dropout層,隨機丟棄30%的神經元,防止過擬

model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))

model.add(layers.Flatten()) # 全連接層(Dense layer)
model.add(layers.Dense(1)) #一個神經元的全連接層,輸出一個單一的實值,用於判斷輸入圖像是真實還是生成的。

return model

測試判別器功能

# 測試判别神經網路
discriminator = make_discriminator_model()

# 預測值越大代表越像
decision = discriminator(generated_image)
print (f'預測值={decision}')
raw-image

4.定義損失函數及優化器

# 使用 TensorFlow 定義的二分類交叉熵損失函數
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

# 定義判别神經網路損失函數為 真實影像 + 生成影像 的損失函數
def discriminator_loss(real_output, fake_output):
'''
真實影像損失 (real_loss):
這部分計算真實影像的損失,即將真實影像的輸出與全為1的標籤比較。
生成影像損失 (fake_loss):
這部分計算生成影像的損失,即將生成影像的輸出與全為0的標籤比較。
'''
real_loss = cross_entropy(tf.ones_like(real_output), real_output)
fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
total_loss = real_loss + fake_loss
return total_loss

# 定義生成神經網路損失函數為 生成影像 的損失函數
def generator_loss(fake_output):
#將生成影像的輸出與全為1的標籤比較。生成器的目標是騙過判别器,使其認為生成的影像是真實的,因此使用全1標籤。
return cross_entropy(tf.ones_like(fake_output), fake_output)

# 優化器均為 Adam
generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

5.儲存檢查點

儲存和復原模型,這在長時間運行的訓練任務中斷時非常有用。

checkpoint_dir = './dcgan_training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,
discriminator_optimizer=discriminator_optimizer,
generator=generator,
discriminator=discriminator)
在Colab儲存示意圖

在Colab儲存示意圖


6.參數設定

這樣的設計確保了生成器和判别器在每個訓練步驟中都能相互對抗,從而提升生成影像的質量。

# 參數設定
EPOCHS = 50 # 訓練執行週期,即整個訓練資料集將被完整地訓練50次。
noise_dim = 100 # 雜訊向量大小,這個向量將作為生成神經網路的輸入。
num_examples_to_generate = 16 # 每次生成的樣本數量。

# 產生亂數(雜訊)'
seed = tf.random.normal([num_examples_to_generate, noise_dim])

# 定義梯度下降,分別對判别神經網路、生成神經網路進行訓練
@tf.function # 產生運算圖 裝飾器將函數編譯成 TensorFlow 運算圖以提高性能。
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, noise_dim])

with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
# 生成神經網路進行訓練
generated_images = generator(noise, training=True)

# 判别神經網路進行訓練
real_output = discriminator(images, training=True) # 真實影像
fake_output = discriminator(generated_images, training=True) # 生成影像

# 計算損失
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(real_output, fake_output)

# 梯度下降
gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss,
discriminator.trainable_variables)

# 更新權重
generator_optimizer.apply_gradients(zip(gradients_of_generator,
generator.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator,
discriminator.trainable_variables))

7.定義訓練函數及產生圖像並存檔

def train(dataset, epochs):
for epoch in range(epochs):
start = time.time()

for image_batch in dataset:
train_step(image_batch)

# 產生圖像
display.clear_output(wait=True)
generate_and_save_images(generator, epoch + 1, seed)

# 每 10 個執行週期存檔一次
if (epoch + 1) % 10 == 0:
checkpoint.save(file_prefix = checkpoint_prefix)

print ('epoch {} 花費 {} 秒'.format(epoch + 1, time.time()-start))

# 顯示最後結果
display.clear_output(wait=True)
generate_and_save_images(generator, epochs, seed)

# 產生圖像並存檔
def generate_and_save_images(model, epoch, test_input):
# 預測
predictions = model(test_input, training=False)

# 顯示 4x4 的格子
fig = plt.figure(figsize=(4, 4))
for i in range(predictions.shape[0]):
plt.subplot(4, 4, i+1)
plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')
plt.axis('off')

# 存檔
plt.savefig('./GAN_result/image_at_epoch_{:04d}.png'.format(epoch))
plt.show()

8.訓練模型

#產生儲存結果的資料夾
import os
if not os.path.exists('./GAN_result'):
  os.makedirs('./GAN_result'

train(train_dataset, EPOCHS) #需要一段時間

9.顯示結果

# 顯示最後結果
def display_image(epoch_no):
return PIL.Image.open('./GAN_result/image_at_epoch_{:04d}.png'.format(epoch_no))

display_image(EPOCHS)

10.將訓練過程的存檔圖像轉為GIF 檔,並顯示GIF檔

要先安裝tensorflow_docs才可以使用它的embed在colab上顯示gif檔

!pip install git+https://github.com/tensorflow/docs
# 產生 GIF
anim_file = './GAN_result/dcgan.gif'
with imageio.get_writer(anim_file, mode='I') as writer: #創建一個 GIF 檔案的寫入器​
filenames = glob.glob('./GAN_result/image*.png') #使用 glob.glob 搜尋符合 image*.png 的所有檔案名稱
filenames = sorted(filenames)
for filename in filenames:
# print(filename)
image = imageio.imread(filename)
writer.append_data(image)

# 顯示 GIF
import tensorflow_docs.vis.embed as embed

embed.embed_file(anim_file)

11.儲存模型

generator.save('DCGAN.h5')


參考文獻


留言
avatar-img
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
148會員
255內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
螃蟹_crab的沙龍的其他內容
2024/07/27
呈上篇介紹如何訓練模型,此篇就主要介紹如何利用訓練好的模型來生成圖片 [深度學習][Python]DCGAN訓練生成手寫阿拉伯數字_生成篇 生成的結果 生成的圖片大小會根據,當初設置的生成器輸出大小來決定,當你使用生成對抗網絡(GAN)生成圖像時,生成器模型的最後一層通常會決定生成圖
Thumbnail
2024/07/27
呈上篇介紹如何訓練模型,此篇就主要介紹如何利用訓練好的模型來生成圖片 [深度學習][Python]DCGAN訓練生成手寫阿拉伯數字_生成篇 生成的結果 生成的圖片大小會根據,當初設置的生成器輸出大小來決定,當你使用生成對抗網絡(GAN)生成圖像時,生成器模型的最後一層通常會決定生成圖
Thumbnail
2024/07/26
本文將延續上一篇文章,經由訓練好的GAN模型中的生成器來生成圖片 [深度學習][Python]訓練MLP的GAN模型來生成圖片_訓練篇 [深度學習][Python]訓練CNN的GAN模型來生成圖片_訓練篇 相較之下CNN的GAN生成的效果比較好,但模型也相對比較複雜,訓練時間花的也比較
Thumbnail
2024/07/26
本文將延續上一篇文章,經由訓練好的GAN模型中的生成器來生成圖片 [深度學習][Python]訓練MLP的GAN模型來生成圖片_訓練篇 [深度學習][Python]訓練CNN的GAN模型來生成圖片_訓練篇 相較之下CNN的GAN生成的效果比較好,但模型也相對比較複雜,訓練時間花的也比較
Thumbnail
2024/07/26
延續上一篇訓練GAM模型,這次我們讓神經網路更多層更複雜一點,來看訓練生成的圖片是否效果會更好。 [深度學習][Python]訓練MLP的GAN模型來生成圖片_訓練篇 資料集分割處理的部分在延續上篇文章,從第五點開始後修改即可,前面都一樣 訓練過程,比較圖 是不是CNN的效果比MLP還要好,
Thumbnail
2024/07/26
延續上一篇訓練GAM模型,這次我們讓神經網路更多層更複雜一點,來看訓練生成的圖片是否效果會更好。 [深度學習][Python]訓練MLP的GAN模型來生成圖片_訓練篇 資料集分割處理的部分在延續上篇文章,從第五點開始後修改即可,前面都一樣 訓練過程,比較圖 是不是CNN的效果比MLP還要好,
Thumbnail
看更多
你可能也想看
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 回顧 AI說書 - 從0開始 - 129 中說,Bidirectional Encoder Representations from Transformers (BER
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 回顧 AI說書 - 從0開始 - 129 中說,Bidirectional Encoder Representations from Transformers (BER
Thumbnail
本篇文章介紹如何使用PyTorch構建和訓練圖神經網絡(GNN),並使用Cora資料集進行節點分類任務。通過模型架構的逐步優化,包括引入批量標準化和獨立的消息傳遞層,調整Dropout和聚合函數,顯著提高了模型的分類準確率。實驗結果表明,經過優化的GNN模型在處理圖結構數據具有強大的性能和應用潛力。
Thumbnail
本篇文章介紹如何使用PyTorch構建和訓練圖神經網絡(GNN),並使用Cora資料集進行節點分類任務。通過模型架構的逐步優化,包括引入批量標準化和獨立的消息傳遞層,調整Dropout和聚合函數,顯著提高了模型的分類準確率。實驗結果表明,經過優化的GNN模型在處理圖結構數據具有強大的性能和應用潛力。
Thumbnail
本文參考TensorFlow官網Deep Convolutional Generative Adversarial Network的程式碼來加以實作說明。 示範如何使用深度卷積生成對抗網路(DCGAN) 生成手寫數位影像。
Thumbnail
本文參考TensorFlow官網Deep Convolutional Generative Adversarial Network的程式碼來加以實作說明。 示範如何使用深度卷積生成對抗網路(DCGAN) 生成手寫數位影像。
Thumbnail
延續上一篇訓練GAM模型,這次我們讓神經網路更多層更複雜一點,來看訓練生成的圖片是否效果會更好。 [深度學習][Python]訓練MLP的GAN模型來生成圖片_訓練篇 資料集分割處理的部分在延續上篇文章,從第五點開始後修改即可,前面都一樣 訓練過程,比較圖 是不是CNN的效果比MLP還要好,
Thumbnail
延續上一篇訓練GAM模型,這次我們讓神經網路更多層更複雜一點,來看訓練生成的圖片是否效果會更好。 [深度學習][Python]訓練MLP的GAN模型來生成圖片_訓練篇 資料集分割處理的部分在延續上篇文章,從第五點開始後修改即可,前面都一樣 訓練過程,比較圖 是不是CNN的效果比MLP還要好,
Thumbnail
本文主要介紹,如何利用GAN生成對抗網路來訓練生成圖片。 利用tensorflow,中的keras來建立生成器及鑑別器互相競爭訓練,最後利用訓練好的生成器來生成圖片。 GAN生成對抗網路的介紹 它由生成網路(Generator Network)和鑑別網路(Discriminator Netwo
Thumbnail
本文主要介紹,如何利用GAN生成對抗網路來訓練生成圖片。 利用tensorflow,中的keras來建立生成器及鑑別器互相競爭訓練,最後利用訓練好的生成器來生成圖片。 GAN生成對抗網路的介紹 它由生成網路(Generator Network)和鑑別網路(Discriminator Netwo
Thumbnail
透過這篇文章,我們將瞭解如何使用PyTorch實作圖神經網絡中的訊息傳遞機制,從定義消息傳遞的類別到實作消息傳遞過程。我們也探討了各種不同的消息傳遞機制,並通過對單次和多次傳遞過程的結果,可以看到節點特徵如何逐步傳遞與更新。
Thumbnail
透過這篇文章,我們將瞭解如何使用PyTorch實作圖神經網絡中的訊息傳遞機制,從定義消息傳遞的類別到實作消息傳遞過程。我們也探討了各種不同的消息傳遞機制,並通過對單次和多次傳遞過程的結果,可以看到節點特徵如何逐步傳遞與更新。
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 Transformer 可以透過繼承預訓練模型 (Pretrained Model) 來微調 (Fine-Tune) 以執行下游任務。 Pretrained Mo
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 Transformer 可以透過繼承預訓練模型 (Pretrained Model) 來微調 (Fine-Tune) 以執行下游任務。 Pretrained Mo
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 Transformers for Natural Language Processing and Computer Vision, 2024 這本書中講 Decoder
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 Transformers for Natural Language Processing and Computer Vision, 2024 這本書中講 Decoder
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 再度回到 Transformer 架構中的 Encoder 部分,如下圖所示: 我現在手上有的素材如下: Embedding 訓練方式:AI說書 - 從0開始
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 再度回到 Transformer 架構中的 Encoder 部分,如下圖所示: 我現在手上有的素材如下: Embedding 訓練方式:AI說書 - 從0開始
Thumbnail
這篇文章探討了生成式對抗網路中機率分佈的使用與相關的訓練方式,包括Generator不同的點、Distriminator的訓練過程、生成圖片的條件設定等。此外,也提到了GAN訓練的困難與解決方式以及不同的learning方式。文章內容豐富且詳細,涵蓋了GAN的各個相關面向。
Thumbnail
這篇文章探討了生成式對抗網路中機率分佈的使用與相關的訓練方式,包括Generator不同的點、Distriminator的訓練過程、生成圖片的條件設定等。此外,也提到了GAN訓練的困難與解決方式以及不同的learning方式。文章內容豐富且詳細,涵蓋了GAN的各個相關面向。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News