<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>「転移学習」タグの記事一覧Python Tech</title>
	<atom:link href="https://tech.nkhn37.net/tag/%E8%BB%A2%E7%A7%BB%E5%AD%A6%E7%BF%92/feed/" rel="self" type="application/rss+xml" />
	<link>https://tech.nkhn37.net</link>
	<description>Python学習サイト</description>
	<lastBuildDate>Sun, 11 Jan 2026 07:29:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://tech.nkhn37.net/wp-content/uploads/2021/01/cropped-lion-normal-clear-1-32x32.png</url>
	<title>「転移学習」タグの記事一覧Python Tech</title>
	<link>https://tech.nkhn37.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【TensorFlow/Keras】訓練済みモデルVGG16での転移学習</title>
		<link>https://tech.nkhn37.net/tensorflow-keras-transfer-learning-vgg16/</link>
					<comments>https://tech.nkhn37.net/tensorflow-keras-transfer-learning-vgg16/#respond</comments>
		
		<dc:creator><![CDATA[naoki-hn]]></dc:creator>
		<pubDate>Sat, 30 Jul 2022 20:00:00 +0000</pubDate>
				<category><![CDATA[TensorFlow]]></category>
		<category><![CDATA[Keras]]></category>
		<category><![CDATA[tensorflow.keras.applications]]></category>
		<category><![CDATA[VGG16]]></category>
		<category><![CDATA[転移学習]]></category>
		<guid isPermaLink="false">https://tech.nkhn37.net/?p=4264</guid>

					<description><![CDATA[TensorFlow/Kerasを用いて、訓練済みモデルVGG16を使った転移学習の方法について解説します。データセットとしてCIFAR10を使って分類への適用をしてみようと思います。 転移学習 転移学習とは、学習済みの [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">TensorFlow/Kerasを用いて、訓練済みモデル<span class="marker"><strong>VGG16</strong></span>を使った<span class="marker"><strong>転移学習</strong></span>の方法について解説します。データセットとしてCIFAR10を使って分類への適用をしてみようと思います。</p>



<h2 class="wp-block-heading jinr-heading d--bold">転移学習</h2>



<p class="wp-block-paragraph"><span class="marker"><strong>転移学習</strong></span>とは、学習済みのモデルを使って新しいモデルの学習を行うことを言います。</p>



<p class="wp-block-paragraph">ディープラーニングでは、大規模なニューラルネットワークを学習させることになるため非常に時間がかかり、データも大量に必要です。このような時に、大量データで既に学習されて公開されているモデルを使うと非常に便利です。</p>



<p class="wp-block-paragraph">転移学習のイメージは以下のような形です。入力後に畳み込み層やプーリング層などの層があり、最後に全結合層の分類器がついているようなモデルだとします。この時、畳み込み層については訓練済みのものをそのまま使用し、最後の分類器の部分を付け替えます。畳み込み層の重みについては凍結して固定した状態にして、新しい分類器部分の重みを訓練することになります。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img fetchpriority="high" decoding="async" width="1024" height="409" src="https://tech.nkhn37.net/wp-content/uploads/2022/07/image-50-1024x409.png" alt="転移学習 概要図" class="wp-image-4265" style="aspect-ratio:2.497560975609756;width:686px;height:auto" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/07/image-50-1024x409.png 1024w, https://tech.nkhn37.net/wp-content/uploads/2022/07/image-50-300x120.png 300w, https://tech.nkhn37.net/wp-content/uploads/2022/07/image-50-768x307.png 768w, https://tech.nkhn37.net/wp-content/uploads/2022/07/image-50.png 1132w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">本記事ではTensorFlow/Kerasを用いた転移学習の実装例を紹介しますが、モデルとしては<span class="marker"><strong>VGG16</strong></span>というものを使用します。</p>



<p class="wp-block-paragraph">VGG16は、2014年にILSVRCという画像認識コンペティションで2位となったモデルで、決して新しい技術のモデルというわけではありませんが、オンライン講座や書籍等で転移学習の説明によく用いられます。本記事でもVGG16の訓練済みモデルを用いて解説をしていこうと思います。</p>



<h2 class="wp-block-heading jinr-heading d--bold">TensorFlow/Kerasで訓練済みモデルのVGG16を用いた画像分類の実装</h2>



<p class="wp-block-paragraph">以降では、TensorFlow/Kerasの訓練済みモデルVGG16を用いた画像分類の実装例を紹介していきます。</p>



<p class="wp-block-paragraph">TensorFlow/Kerasでは、<span class="marker"><strong>tensorflow.keras.applications</strong></span>にImageNetという大規模なデータセットで学習した画像分類モデルと重みが使えるようになっています。VGG16の他にもResNet、DenseNet等のより新しいモデルもあります。</p>



<p class="wp-block-paragraph">また、今回例に使うデータセットはCIFAR10（サイファーテン）というデータセットです。CIFAR10は10種類の画像のデータセットで32×32のサイズで、RGBの3チャンネルを持つデータセットとなっています。各ラベルは以下の対応となっています。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--simple-box1  "><div class="c--simple-box-inner">
<ul class="wp-block-list jinr-list">
<li>0：飛行機</li>



<li>1：自動車</li>



<li>2：鳥</li>



<li>3：猫</li>



<li>4：鹿</li>



<li>5：犬</li>



<li>6：蛙</li>



<li>7：馬</li>



<li>8：船</li>



<li>9：トラック</li>
</ul>
</div></div></section>



<h3 class="wp-block-heading jinr-heading d--bold">実装例</h3>



<p class="wp-block-paragraph">以下に、TensorFlow/Kerasを用いた実装例を示します。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import matplotlib.pyplot as plt
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.optimizers import SGD


def main():
    """メイン関数"""

    (train_imgs, train_labels), (test_imgs, test_labels) = cifar10.load_data()
    # 訓練データの一部(20%)を評価データとして使う
    idx = int(train_imgs.shape[0] * 0.2)
    train_imgs, val_imgs = train_imgs[idx:], train_imgs[:idx]
    train_labels, val_labels = train_labels[idx:], train_labels[:idx]

    # ===== VGG16で事前に学習されたモデルを読み込む
    vgg16 = VGG16(include_top=False, weights="imagenet", input_shape=(32, 32, 3))

    # ===== 新しい出力用分類モデルを作成する
    # VGG16の出力を平坦化して全結合層へ接続
    x = layers.Flatten()(vgg16.output)
    x = layers.Dense(256, activation="relu")(x)
    x = layers.Dropout(0.5)(x)
    # 分類のために10ノードに接続
    outputs = layers.Dense(10, activation="softmax")(x)

    # モデルの作成
    model = keras.Model(inputs=vgg16.input, outputs=outputs)

    # 0~18までのlayerがVGG16に関連するので重みを固定する
    for layer in model.layers[:19]:
        layer.trainable = False

    # モデル構成の表示&amp;画像保存
    print(model.summary())
    keras.utils.plot_model(
        model, "transfer_learning_vgg16_cifar10.png", show_shapes=True
    )

    # ===== オプティマイザ、損失関数、指標を設定してコンパイル
    # 転移学習の場合、最適化関数はSGDの選択がよいとされている
    model.compile(
        optimizer=SGD(learning_rate=1e-4, momentum=0.9),
        loss="sparse_categorical_crossentropy",
        metrics=["accuracy"],
    )

    # ===== fitを使ったモデルの訓練
    # 設定
    num_epochs = 10
    callbacks = [
        keras.callbacks.ModelCheckpoint("vgg16_cifar10.keras", save_best_only=True)
    ]
    # 訓練の実行
    history = model.fit(
        train_imgs,
        train_labels,
        epochs=num_epochs,
        batch_size=32,
        validation_data=(val_imgs, val_labels),
        callbacks=callbacks,
    )

    # ===== history情報の可視化
    # 損失関数(loss)の履歴
    loss = history.history["loss"]
    val_loss = history.history["val_loss"]
    # 正解率(accuracy)の履歴
    acc = history.history["accuracy"]
    val_acc = history.history["val_accuracy"]

    # 損失関数の履歴描画
    x_epoch = range(1, num_epochs + 1)
    plt.plot(x_epoch, loss, "r", label="training loss")
    plt.plot(x_epoch, val_loss, "b", label="validation loss")
    plt.xlabel("Epochs")
    plt.ylabel("Loss")
    plt.legend()
    # 正解率の履歴描画
    plt.figure()
    plt.plot(x_epoch, acc, "r", label="training acc")
    plt.plot(x_epoch, val_acc, "b", label="validation acc")
    plt.xlabel("Epochs")
    plt.ylabel("Accuracy")
    plt.legend()

    plt.show()

    # ===== evaluateを使ったテストデータでの評価
    result = model.evaluate(test_imgs, test_labels)
    print(result)

    # ===== predictを使って予測結果を表示
    preds = model.predict(test_imgs)
    print(f"予測: {np.argmax(preds[0])}, 正解: {test_labels[0]}")


if __name__ == "__main__":
    main()</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">【実行結果例】
Model: "model"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_1 (InputLayer)        [(None, 32, 32, 3)]       0         
                                                                 
 block1_conv1 (Conv2D)       (None, 32, 32, 64)        1792      
                                                                 
 block1_conv2 (Conv2D)       (None, 32, 32, 64)        36928     
                                                                 
 block1_pool (MaxPooling2D)  (None, 16, 16, 64)        0         
                                                                 
 block2_conv1 (Conv2D)       (None, 16, 16, 128)       73856     
                                                                 
 block2_conv2 (Conv2D)       (None, 16, 16, 128)       147584    
                                                                 
 block2_pool (MaxPooling2D)  (None, 8, 8, 128)         0         
                                                                 
 block3_conv1 (Conv2D)       (None, 8, 8, 256)         295168    
                                                                 
 block3_conv2 (Conv2D)       (None, 8, 8, 256)         590080    
                                                                 
 block3_conv3 (Conv2D)       (None, 8, 8, 256)         590080    
                                                                 
 block3_pool (MaxPooling2D)  (None, 4, 4, 256)         0         
                                                                 
 block4_conv1 (Conv2D)       (None, 4, 4, 512)         1180160   
                                                                 
 block4_conv2 (Conv2D)       (None, 4, 4, 512)         2359808   
                                                                 
 block4_conv3 (Conv2D)       (None, 4, 4, 512)         2359808   
                                                                 
 block4_pool (MaxPooling2D)  (None, 2, 2, 512)         0         
                                                                 
 block5_conv1 (Conv2D)       (None, 2, 2, 512)         2359808   
                                                                 
 block5_conv2 (Conv2D)       (None, 2, 2, 512)         2359808   
                                                                 
 block5_conv3 (Conv2D)       (None, 2, 2, 512)         2359808   
                                                                 
 block5_pool (MaxPooling2D)  (None, 1, 1, 512)         0         
                                                                 
 flatten (Flatten)           (None, 512)               0         
                                                                 
 dense (Dense)               (None, 256)               131328    
                                                                 
 dropout (Dropout)           (None, 256)               0         
                                                                 
 dense_1 (Dense)             (None, 10)                2570      
                                                                 
=================================================================
Total params: 14,848,586
Trainable params: 133,898
Non-trainable params: 14,714,688
_________________________________________________________________
None
Epoch 1/10
1250/1250 [==============================] - 27s 19ms/step - loss: 4.3056 - accuracy: 0.3212 - val_loss: 1.7398 - val_accuracy: 0.4300
Epoch 2/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.9014 - accuracy: 0.3829 - val_loss: 1.5865 - val_accuracy: 0.4664
Epoch 3/10
1250/1250 [==============================] - 25s 20ms/step - loss: 1.7367 - accuracy: 0.4121 - val_loss: 1.5123 - val_accuracy: 0.4869
Epoch 4/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.6590 - accuracy: 0.4293 - val_loss: 1.4693 - val_accuracy: 0.4943
Epoch 5/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.5964 - accuracy: 0.4473 - val_loss: 1.4328 - val_accuracy: 0.5095
Epoch 6/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.5425 - accuracy: 0.4602 - val_loss: 1.4105 - val_accuracy: 0.5155
Epoch 7/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.5128 - accuracy: 0.4660 - val_loss: 1.3926 - val_accuracy: 0.5183
Epoch 8/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.4788 - accuracy: 0.4768 - val_loss: 1.3661 - val_accuracy: 0.5300
Epoch 9/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.4543 - accuracy: 0.4858 - val_loss: 1.3529 - val_accuracy: 0.5359
Epoch 10/10
1250/1250 [==============================] - 24s 19ms/step - loss: 1.4379 - accuracy: 0.4933 - val_loss: 1.3401 - val_accuracy: 0.5398
313/313 [==============================] - 5s 15ms/step - loss: 1.3503 - accuracy: 0.5351
[1.3502779006958008, 0.535099983215332]
313/313 [==============================] - 4s 14ms/step
予測: 6, 正解: [3]</pre>



<div class="wp-block-columns js--scr-animation is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="547" height="406" src="https://tech.nkhn37.net/wp-content/uploads/2022/07/image-51.png" alt="VGG16 転移学習 損失値" class="wp-image-4271" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/07/image-51.png 547w, https://tech.nkhn37.net/wp-content/uploads/2022/07/image-51-300x223.png 300w" sizes="(max-width: 547px) 100vw, 547px" /></figure>
</div></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img decoding="async" width="544" height="410" src="https://tech.nkhn37.net/wp-content/uploads/2022/07/image-52.png" alt="VGG16 転移学習 正解率" class="wp-image-4272" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/07/image-52.png 544w, https://tech.nkhn37.net/wp-content/uploads/2022/07/image-52-300x226.png 300w" sizes="(max-width: 544px) 100vw, 544px" /></figure>
</div>
</div>



<p class="wp-block-paragraph">精度は約54%台と全然高くはありません。また、今回実行してみた限り、最初(0番目)のデータに対する予測は失敗してしまっています。訓練データのかさ増しや繰り返しによりもっと精度が出るようですが、今回は転移学習の実装方法を示すということで深堀りはしません。</p>



<h3 class="wp-block-heading jinr-heading d--bold">実装内容の解説</h3>



<p class="wp-block-paragraph">上記で紹介した実装例の各部分ごとの内容を説明していきます。</p>



<p class="wp-block-paragraph"><strong>必要モジュールのインポート</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import matplotlib.pyplot as plt
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.optimizers import SGD</pre>



<p class="wp-block-paragraph">まずは、必要なモジュール類をインポートします。<span class="marker"><strong>VGG16</strong></span>はtensorflow.keras.applications.vgg16からインポートします。また、データセットとしてはKeras内のCIFAR10がありますのであわせてインポートしています。</p>



<p class="wp-block-paragraph"><strong>データセットの用意</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    (train_imgs, train_labels), (test_imgs, test_labels) = cifar10.load_data()
    # 訓練データの一部(20%)を評価データとして使う
    idx = int(train_imgs.shape[0] * 0.2)
    train_imgs, val_imgs = train_imgs[idx:], train_imgs[:idx]
    train_labels, val_labels = train_labels[idx:], train_labels[:idx]</pre>



<p class="wp-block-paragraph">今回使用するCIFAR10データセットを準備します。読み込みはload_data()で実行できます。また、訓練データのうち20%を検証データとして抜き出しています。</p>



<p class="wp-block-paragraph"><strong>VGG16モデルを読み込む</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # ===== VGG16で事前に学習されたモデルを読み込む
    vgg16 = VGG16(include_top=False, weights="imagenet", input_shape=(32, 32, 3))</pre>



<p class="wp-block-paragraph">ここから転移学習に関する部分に入っていきます。インポートしたVGG16をインスタンス化します。</p>



<p class="wp-block-paragraph">include_topは、全結合分類器を含めるかどうかを指定するものでTrueにするとImageNetの1,000個のクラスへの分類器となりますが、今回新しい分類器を後で追加するのでFalseとします。</p>



<p class="wp-block-paragraph">weightsは&#8217;imagenet&#8217;、input_shapeはCIFAR10の入力形状である(32, 32, 3)を指定しています。</p>



<p class="wp-block-paragraph"><strong>新しい分類モデルを作成し、VGG16モデルから接続する</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # ===== 新しい出力用分類モデルを作成する
    # VGG16の出力を平坦化して全結合層へ接続
    x = layers.Flatten()(vgg16.output)
    x = layers.Dense(256, activation="relu")(x)
    x = layers.Dropout(0.5)(x)
    # 分類のために10ノードに接続
    outputs = layers.Dense(10, activation="softmax")(x)</pre>



<p class="wp-block-paragraph">ここでは、新しい分類モデルを作成し、VGG16モデルの出力を接続しています。</p>



<p class="wp-block-paragraph">まずはFlattenで平坦化し、その後256ノードの全結合層、ドロップアウト、分類のための10ノードの全結合層といった形で接続をしています。</p>



<p class="wp-block-paragraph"><strong>モデルの作成と重みの凍結</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # モデルの作成
    model = keras.Model(inputs=vgg16.input, outputs=outputs)

    # 0~18までのlayerがVGG16に関連するので重みを固定する
    for layer in model.layers[:19]:
        layer.trainable = False

    # モデル構成の表示&amp;画像保存
    print(model.summary())
    keras.utils.plot_model(
        model, "transfer_learning_vgg16_cifar10.png", show_shapes=True
    )</pre>



<p class="wp-block-paragraph">モデルの作成はkeras.Modelにインプットとアウトプットを指定します。inputsはvgg16.inputで、outputsは先ほど作成した分類器の出力を指定します。</p>



<p class="wp-block-paragraph">model.layersに各層が保存されているわけですが、0~18についてはVGG16に関する層です。この部分の重みは凍結（固定）したいので、for文を使ってtrainableをFalseと設定します。summaryでモデルを表示していますが、以下のようにVGG16の部分の重みがNon-trainable paramsになることが分かります。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Total params: 14,848,586
Trainable params: 133,898
Non-trainable params: 14,714,688</pre>



<p class="wp-block-paragraph">また、keras.utils.plot_modelでモデルの可視化をしています。block5_poolまでがVGG16のモデルで、それ以降が今回個別に追加した部分です。</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" width="387" height="2508" src="https://tech.nkhn37.net/wp-content/uploads/2022/07/transfer_learning_vgg16_cifar10.png" alt="VGG16を用いた転移学習" class="wp-image-4274" style="width:353px;height:auto" srcset="https://tech.nkhn37.net/wp-content/uploads/2022/07/transfer_learning_vgg16_cifar10.png 387w, https://tech.nkhn37.net/wp-content/uploads/2022/07/transfer_learning_vgg16_cifar10-158x1024.png 158w, https://tech.nkhn37.net/wp-content/uploads/2022/07/transfer_learning_vgg16_cifar10-237x1536.png 237w, https://tech.nkhn37.net/wp-content/uploads/2022/07/transfer_learning_vgg16_cifar10-316x2048.png 316w" sizes="(max-width: 387px) 100vw, 387px" /></figure>
</div>


<p class="wp-block-paragraph"><strong>モデルのコンパイル</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # ===== オプティマイザ、損失関数、指標を設定してコンパイル
    # 転移学習の場合、最適化関数はSGDの選択がよいとされている
    model.compile(
        optimizer=SGD(learning_rate=1e-4, momentum=0.9),
        loss="sparse_categorical_crossentropy",
        metrics=["accuracy"],
    )</pre>



<p class="wp-block-paragraph">モデルのコンパイルは<span class="marker"><strong>compile</strong></span>を使用します。optimizer、loss、metricsでそれぞれ指定します。</p>



<section class="wp-block-jinr-blocks-iconbox b--jinr-block b--jinr-iconbox"><div class="d--simple-iconbox5 ">
			<i class="jif jin-ifont-v2speaker" aria-hidden="true"></i>
			<div class="a--jinr-iconbox">
<p class="wp-block-paragraph">転移学習をする場合、最適化（optimizer）は、確率的勾配降下法（<strong>SGD</strong>）を選択するのがよいとされています。ただし、必ずしも最適とは限りませんので色々な方法を試してみてください。</p>
</div>
		</div></section>



<p class="wp-block-paragraph"><strong>モデルの訓練（学習）</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # ===== fitを使ったモデルの訓練
    # 設定
    num_epochs = 10
    callbacks = [
        keras.callbacks.ModelCheckpoint("vgg16_cifar10.keras", save_best_only=True)
    ]
    # 訓練の実行
    history = model.fit(
        train_imgs,
        train_labels,
        epochs=num_epochs,
        batch_size=32,
        validation_data=(val_imgs, val_labels),
        callbacks=callbacks,
    )</pre>



<p class="wp-block-paragraph">モデルの訓練は<span class="marker"><strong>fit</strong></span>で実行します。今回はエポックは10としましたが、数字は変更して試してみてください。評価用のデータとしてvalidation_dataを指定しています。</p>



<p class="wp-block-paragraph">また、callbackを使ってチェックポイントとしてモデルを保存しています。save_best_only=Trueとすることで最もよいモデルのみ保存します。保存したモデルを読み込んで使う場合は例えば以下のように使用することができます。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import numpy as np
from tensorflow import keras
from tensorflow.keras.datasets import cifar10


def main():
    _, (test_imgs, test_labels) = cifar10.load_data()

    model = keras.models.load_model("vgg16_cifar10.keras")

    # ===== evaluateを使ったテストデータでの評価
    result = model.evaluate(test_imgs, test_labels)
    print(result)

    # ===== predictを使って予測結果を表示
    preds = model.predict(test_imgs)
    print(f"予測: {np.argmax(preds[0])}, 正解: {test_labels[0]}")


if __name__ == "__main__":
    main()</pre>



<p class="wp-block-paragraph"><strong>訓練（学習）状況の可視化</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # ===== history情報の可視化
    # 損失関数(loss)の履歴
    loss = history.history["loss"]
    val_loss = history.history["val_loss"]
    # 正解率(accuracy)の履歴
    acc = history.history["accuracy"]
    val_acc = history.history["val_accuracy"]

    # 損失関数の履歴描画
    x_epoch = range(1, num_epochs + 1)
    plt.plot(x_epoch, loss, "r", label="training loss")
    plt.plot(x_epoch, val_loss, "b", label="validation loss")
    plt.xlabel("Epochs")
    plt.ylabel("Loss")
    plt.legend()
    # 正解率の履歴描画
    plt.figure()
    plt.plot(x_epoch, acc, "r", label="training acc")
    plt.plot(x_epoch, val_acc, "b", label="validation acc")
    plt.xlabel("Epochs")
    plt.ylabel("Accuracy")
    plt.legend()

    plt.show()</pre>



<p class="wp-block-paragraph">fitは返却値として、損失関数や指標の推移(history)を返却します。上記の部分では、historyの中に保存されている損失関数(loss)の履歴と正解率(accuracy)の履歴を取得してきて、matplotlibのplotで描画しています。なお、val_xxxとなっているものについては、評価データに対する値になります。</p>



<p class="wp-block-paragraph"><strong>テストデータでの評価及び予測</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    # ===== evaluateを使ったテストデータでの評価
    result = model.evaluate(test_imgs, test_labels)
    print(result)

    # ===== predictを使って予測結果を表示
    preds = model.predict(test_imgs)
    print(f"予測: {np.argmax(preds[0])}, 正解: {test_labels[0]}")</pre>



<p class="wp-block-paragraph">上記の部分はテストデータを使った評価と予測に関する部分です。テストデータを使った評価は<span class="marker"><strong>evaluate</strong></span>を用いて実行できます。結果は[損失(loss), 正解率(accuracy)]という形で返ってきます。</p>



<p class="wp-block-paragraph">また、予測結果は<span class="marker"><strong>predict</strong></span>を用いて実行できます。今回のモデルは各文字に対する確率値が計算されます。そのため、予測結果としては確率が最も高い値となるため、argmaxで取得しています。</p>



<p class="wp-block-paragraph">以上が、TensorFlow/Kerasを用いて訓練済みモデルのVGG16を用いた転移学習の実装例です。</p>



<h2 class="wp-block-heading jinr-heading d--bold">まとめ</h2>



<p class="wp-block-paragraph"><span class="marker"><strong>VGG16</strong></span>という訓練済みモデルを用いて、転移学習する実装例について紹介しました。データセットとしてはCIFAR10を用いています。</p>



<p class="wp-block-paragraph">VGG16は最新のモデルというようなものではありませんが、転移学習のイメージをつかむためにはよく説明に使用されるものとなっています。KerasにはVGG16の他にもResNetやDenseNet等の他の訓練済みモデルも用意されています。</p>



<p class="wp-block-paragraph">是非色々な問題で訓練済みモデルを用いた転移学習を試してみてもらいたいと思います。</p>



<section class="wp-block-jinr-blocks-simplebox b--jinr-block-container"><div class="b--jinr-block b--jinr-box d--heading-box8  "><div class="a--simple-box-title d--bold">ソースコード</div><div class="c--simple-box-inner">
<p class="wp-block-paragraph">上記で紹介しているソースコードについては <a href="https://github.com/nkhn37/python-tech-sample-source/tree/main/python-data-analysis/tensorflow/transfer-learning/vgg16" target="_blank" rel="noreferrer noopener">GitHub</a> にて公開しています。参考にしていただければと思います。</p>
</div></div></section>


<section class="b--jinr-block b--jinr-blogcard d--blogcard-hover-up d--blogcard-style1 d--blogcard-mysite t--round "><div class="a--blogcard-label ef">あわせて読みたい</div><a class="o--blogcard-link t--round" href="https://tech.nkhn37.net/python-tech-summary-page/"><div class="c--blogcard-image"><img decoding="async" class="a--blogcard-img-src" width="128" height="72" src="https://tech.nkhn37.net/wp-content/uploads/2024/08/Python-Tech-Pythonプログラミングガイド_new1-640x360.jpg" alt="【Python Tech】プログラミングガイド" /></div><div class="a--blogcard-title d--bold">【Python Tech】プログラミングガイド</div></a></section>




<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.nkhn37.net/tensorflow-keras-transfer-learning-vgg16/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: tech.nkhn37.net @ 2026-06-12 12:35:48 by W3 Total Cache
-->