9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CNNの有名なモデルをTensorFlowで実装する

Last updated at Posted at 2023-04-14

今日はCNNについて勉強したので、自分用も兼ねて、tensorflowで実装したものを記事にします。

CNN

CNNとは

 CNNとは、主に画像認識や画像分類などのタスクで用いられるニューラルネットワークのこと。畳み込み層とプーリング層、全結合層という層を持つのが特徴。
 Convolutional Neural Networkの略で、日本語だと畳み込みニューラルネットワークと言う。

CNNの実装

シンプルなCNNを実装します。
tensorflowにConv2Dがあるので使います。

import tensorflow as tf

model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)),
  tf.keras.layers.MaxPooling2D((2,2)),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(10, activation='softmax')
])

AlexNet

AlexNetとは

 AlexNetとは、CNNの一つで、2012年にAIの画像認識の大会で2位に大差をつけて優勝したモデル。
 現在のAIブーム/ディープラーニングブームのきっかけになった。

構造

AlexNet
出典:https://www.researchgate.net/figure/An-illustration-of-the-architecture-of-AlexNet-CNN-14_fig4_312188377

実装

def alexet(input_shape=(227, 227, 3), num_classes=1000):
    model = models.Sequential()

    model.add(layers.Conv2D(96, (11, 11), strides=(4, 4), activation='relu', input_shape=input_shape, padding="valid"))
    model.add(layers.BatchNormalization())
    model.add(layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding="valid"))

    model.add(layers.Conv2D(256, (5, 5), strides=(1, 1), activation='relu', padding="same"))
    model.add(layers.BatchNormalization())
    model.add(layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding="valid"))

    model.add(layers.Conv2D(384, (3, 3), strides=(1, 1), activation='relu', padding="same"))

    model.add(layers.Conv2D(384, (3, 3), strides=(1, 1), activation='relu', padding="same"))

    model.add(layers.Conv2D(256, (3, 3), strides=(1, 1), activation='relu', padding="same"))
    model.add(layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding="valid"))

    model.add(layers.Flatten())

    model.add(layers.Dense(4096, activation='relu'))
    model.add(layers.Dropout(0.5))

    model.add(layers.Dense(4096, activation='relu'))
    model.add(layers.Dropout(0.5))

    model.add(layers.Dense(num_classes, activation='softmax'))

    return model

VGG16

VGG16は、16層からなるモデル。ILSVRC2014で準優勝。

構造

image.png
出典:http://www.sanko-shoko.net/note.php?id=pyk1

def vgg16(input_shape=(224, 224, 3), num_classes=1000):
    model = models.Sequential()

    model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=input_shape))
    model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
    model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))


    model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
    model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))


    model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
    model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))


    model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
    model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))


    model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
    model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
    model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))


    model.add(layers.Flatten())
    model.add(layers.Dense(4096, activation='relu'))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(4096, activation='relu'))
    model.add(layers.Dropout(0.5))

    model.add(layers.Dense(num_classes, activation='softmax'))

    return model

ResNet

ILSVRC2015優勝
通常の畳み込みネットワークにショートカット接続を加えた構造
image.png
出典:https://arxiv.org/abs/1512.03385

実装

学習済みのモデルが公開されているのでそれを使います。楽なので嬉しい

import tensorflow as tf
from tensorflow.keras.applications.resnet50 import ResNet50

# 学習済みの重みを持つ ResNet50 モデルを作成
model = ResNet50(weights='imagenet')

model.summary()

ショートカット接続も実装します。
最初全然分からなくいて、はじめて意味が分かった時はうれしかったです。

def identity_block(input_tensor, kernel_size, filters):
    filters1, filters2, filters3 = filters

    x = layers.Conv2D(filters1, (1, 1))(input_tensor)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)

    x = layers.Conv2D(filters2, kernel_size, padding='same')(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)

    x = layers.Conv2D(filters3, (1, 1))(x)
    x = layers.BatchNormalization()(x)

    # ショートカット接続 
    x = layers.add([x, input_tensor])
    x = layers.Activation('relu')(x)

    return x

肝は

    # ショートカット接続 
    x = layers.add([x, input_tensor])

の部分です。
ここで現在の残差ブロックの特徴マップxにショートカット接続の入力input_tenosrが加算されます。

EfficientNet

Googleが開発したCNN。
モデル最適化を行うことで、計算効率と高い精度を同時に実現している。

実装

これも学習済みのモデルが公開されているので使います。うれし。
正直このあたりは、構造を見ても自分には理解できないです。

import tensorflow as tf
from tensorflow.keras.applications import EfficientNetB0

model = EfficientNetB0(weights='imagenet')

model.summary()
9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?