First, preliminary work

This paper will realize the identification of personas in One Piece king.

My environment:

  • Locale: Python3.6.5
  • Compiler: Jupyter Notebook
  • Deep learning environment: TensorFlow2.4.1

Recommended Reading:

  • Depth study of 100 cases – convolution neural network (CNN) implementation mnist handwritten numeral recognition | 1 day
  • Deep learning 100 cases – convolution neural network (CNN) color image classification | 2 days
  • Depth study of 100 cases – convolution neural network (CNN) weather identification | 5 days
  • Depth study of 100 cases (VGG – 19) – convolution neural network to identify the spirit the characters in the cage | 7 days

From the column:100 Examples of Deep Learning

1. Set the GPU

You can skip this step if you are using a CPU

import tensorflow as tf

gpus = tf.config.list_physical_devices("GPU")

if gpus:
    tf.config.experimental.set_memory_growth(gpus[0].True)  # Set GPU memory usage as required
    tf.config.set_visible_devices([gpus[0]],"GPU")
Copy the code

2. Import data

import matplotlib.pyplot as plt
import os,PIL

# Set random seeds to reproduce the results as much as possible
import numpy as np
np.random.seed(1)

# Set random seeds to reproduce the results as much as possible
import tensorflow as tf
tf.random.set_seed(1)

from tensorflow import keras
from tensorflow.keras import layers,models

import pathlib
Copy the code
data_dir = "D:\jupyter notebook\DL-100-days\datasets\hzw_photos"

data_dir = pathlib.Path(data_dir)
Copy the code

3. View data

There are seven characters in the data set, including Luffy, Sauron, Nami, Usopo, Jabbar, Sanji and Robin

folder meaning The number of
lufei luffy 117
suolong sauron 90
namei Her beauty 84
wusuopu Wu thorpe 77
qiaoba Joe, 102
shanzhi sanji 47 a
luobin Robin, 105
image_count = len(list(data_dir.glob('*/*.png')))

print("The total number of pictures is:",image_count)
Copy the code
Total number of pictures: 621Copy the code

2. Data preprocessing

1. Load data

Use the image_DATASet_from_directory method to load the data from the disk into tf.data.dataset

batch_size = 32
img_height = 224
img_width = 224
Copy the code
"" "about image_dataset_from_directory () articles detailing can refer to: https://mtyjkh.blog.csdn.net/article/details/117018789, "" "
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)
Copy the code
Found 621 files belonging to 7 classes.
Using 497 files for training.
Copy the code
"" "about image_dataset_from_directory () articles detailing can refer to: https://mtyjkh.blog.csdn.net/article/details/117018789, "" "
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)
Copy the code
Found 621 files belonging to 7 classes.
Using 124 files for validation.
Copy the code

We can output the labels of the dataset through class_names. The labels will correspond alphabetically to the directory name.

class_names = train_ds.class_names
print(class_names)
Copy the code
['lufei', 'luobin', 'namei', 'qiaoba', 'shanzhi', 'suolong', 'wusuopu']
Copy the code

2. Visualize data

plt.figure(figsize=(10.5))  The width of the figure is 10 and the height is 5

for images, labels in train_ds.take(1) :for i in range(8):
        
        ax = plt.subplot(2.4, i + 1)  

        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])
        
        plt.axis("off")
Copy the code

plt.imshow(images[1].numpy().astype("uint8"))
Copy the code
<matplotlib.image.AxesImage at 0x2adcea36ee0>
Copy the code

3. Check the data again

for image_batch, labels_batch in train_ds:
    print(image_batch.shape)
    print(labels_batch.shape)
    break
Copy the code
(32, 224, 224, 3)
(32,)
Copy the code
  • Image_batchIs the tensor of the shape (32,180,180,3). This is a batch of 32 images with the shape 180x180x3 (the last dimension refers to the color channel RGB).
  • Label_batchIs the tensor of the shape (32,), and these labels correspond to 32 pictures

4. Configure the data set

  • Shuffle () : disturb data, detailed introduction about this function can be reference: zhuanlan.zhihu.com/p/42417456
  • Prefetch () : The process of prefetching data to speed up a run is described in my previous two articles.
  • Cache () : The data set is cached in memory to speed up operation
AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
Copy the code

5. The normalized

normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)

normalization_train_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
val_ds = val_ds.map(lambda x, y: (normalization_layer(x), y))
Copy the code
image_batch, labels_batch = next(iter(val_ds))
first_image = image_batch[0]

# View normalized data
print(np.min(first_image), np.max(first_image))
Copy the code
0.0 0.9928046
Copy the code

Iii. Build vGG-16 network

Between the official model and the self-built model to choose one, choose one comment out the other, are legitimate VGG-16 ha.

VGG advantages and disadvantages analysis:

  • VGG advantages

The structure of VGG is very simple, with the same convolution kernel size (3×3) and maximum pooling size (2×2) used throughout the network.

  • VGG shortcomings

1) The training time is too long and the adjustment is difficult. 2) The required storage capacity is large, which is not conducive to deployment. For example, the size of the vGG-16 weight value file is more than 500 MB, which is not suitable for installation in an embedded system.

1. Official model (packaged)

I’ll leave this part of the official website model invocation in the next few articles, but I’ll focus on VGG-16

# model = keras.applications.VGG16()
# model.summary()
Copy the code

2. Self-built model

from tensorflow.keras import layers, models, Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout

def VGG16(nb_classes, input_shape) :
    input_tensor = Input(shape=input_shape)
    # 1st block
    x = Conv2D(64, (3.3), activation='relu', padding='same',name='block1_conv1')(input_tensor)
    x = Conv2D(64, (3.3), activation='relu', padding='same',name='block1_conv2')(x)
    x = MaxPooling2D((2.2), strides=(2.2), name = 'block1_pool')(x)
    # 2nd block
    x = Conv2D(128, (3.3), activation='relu', padding='same',name='block2_conv1')(x)
    x = Conv2D(128, (3.3), activation='relu', padding='same',name='block2_conv2')(x)
    x = MaxPooling2D((2.2), strides=(2.2), name = 'block2_pool')(x)
    # 3rd block
    x = Conv2D(256, (3.3), activation='relu', padding='same',name='block3_conv1')(x)
    x = Conv2D(256, (3.3), activation='relu', padding='same',name='block3_conv2')(x)
    x = Conv2D(256, (3.3), activation='relu', padding='same',name='block3_conv3')(x)
    x = MaxPooling2D((2.2), strides=(2.2), name = 'block3_pool')(x)
    # 4th block
    x = Conv2D(512, (3.3), activation='relu', padding='same',name='block4_conv1')(x)
    x = Conv2D(512, (3.3), activation='relu', padding='same',name='block4_conv2')(x)
    x = Conv2D(512, (3.3), activation='relu', padding='same',name='block4_conv3')(x)
    x = MaxPooling2D((2.2), strides=(2.2), name = 'block4_pool')(x)
    # 5th block
    x = Conv2D(512, (3.3), activation='relu', padding='same',name='block5_conv1')(x)
    x = Conv2D(512, (3.3), activation='relu', padding='same',name='block5_conv2')(x)
    x = Conv2D(512, (3.3), activation='relu', padding='same',name='block5_conv3')(x)
    x = MaxPooling2D((2.2), strides=(2.2), name = 'block5_pool')(x)
    # full connection
    x = Flatten()(x)
    x = Dense(4096, activation='relu',  name='fc1')(x)
    x = Dense(4096, activation='relu', name='fc2')(x)
    output_tensor = Dense(nb_classes, activation='softmax', name='predictions')(x)

    model = Model(input_tensor, output_tensor)
    return model

model=VGG16(1000, (img_width, img_height, 3))
model.summary()
Copy the code
Model: "model" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) [(None, 224, 224, 3)] 0 _________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ block1_conv2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ block1_pool (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ block2_conv1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ block2_conv2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ block2_pool (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ block3_conv1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ block3_conv2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_conv3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_pool (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_pool (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_pool (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc1 (Dense) (None, 4096) 102764544 _________________________________________________________________ fc2 (Dense) (None, 4096) 16781312 _________________________________________________________________ predictions (Dense) (None, 1000) 4097000 ================================================================= Total params: Trainable Params: 138,357,544 0 _________________________________________________________________Copy the code

3. Network structure diagram

Knowledge about convolution can refer to the article: mtyjkh.blog.csdn.net/article/det…

Structure description:

  • The 13 Convolutional layers are used respectivelyblockX_convXsaid
  • Three Fully connected layers are used separatelyfcXwithpredictionssaid
  • Five Pool layers, respectivelyblockX_poolsaid

VGG-16Contains 16 hidden layers (13 convolution layers and 3 fully connected layers), so it is calledVGG-16

Four, compile,

Before you are ready to train the model, you need to set it up a little more. The following was added in the build step of the model:

  • Loss function: Used to measure the accuracy of the model during training.
  • Optimizer: Determines how the model is updated based on the data it sees and its own loss function.
  • Metrics: Used to monitor training and testing steps. The following example uses accuracy, which is the ratio of images that are correctly classified.
# Set optimizer
opt = tf.keras.optimizers.Adam(learning_rate=1e-4)

model.compile(optimizer=opt,
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
Copy the code

5. Training model

epochs = 20

history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs
)
Copy the code
Epoch 1/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 14 461 ms/s step - loss: 4.5842 accuracy: 0.1349 - val_loss: 6.8389 - val_accuracy: 0.1129 Epoch 2/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 146 ms/s step - loss: 2.1046 - accuracy: 0.1398-val_loss: 6.7905-val_accuracy: 0.2016 Epoch 3/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 144 ms/s step - loss: 1.7885 accuracy: 0.3531 - val_loss: 6.7892 - val_accuracy: 0.2903 Epoch 4/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 145 ms/s step - loss: 1.2015 - accuracy: 0.6135-val_loss: 6.7532-val_accuracy: 0.2742 Epoch 5/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 148 ms/s step - loss: 1.1831 accuracy: 0.6108 - val_loss: 6.7520 - val_accuracy: 0.4113 Epoch 6/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 143 ms/s step - loss: Accuracy: 0.5140 - accuracy: 0.8326-val_loss: 6.7102-val_accuracy: 0.5806 Epoch 7/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 150 ms/s step - loss: 0.2451 accuracy: 0.9165 - val_loss: 6.6918 - val_accuracy: 0.7823 Epoch 8/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 147 ms/s step - loss: 0.2156 - accuracy: 0.9328-val_loss: 6.7188-val_accuracy: 0.4113 Epoch 9/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 143 ms/s step - loss: 0.1940 accuracy: 0.9513 - val_loss: 6.6639 - val_accuracy: 0.5968 Epoch 10/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 143 ms/s step - loss: 0.0767 - accuracy: 0.9812 - val_loss: 6.6101-val_accuracy: 0.7419 Epoch 11/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 146 ms/s step - loss: 0.0245 accuracy: 0.9894 - val_loss: 6.5526 - val_accuracy: 0.8226 Epoch 12/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 149 ms/s step - loss: 0.0387 - accuracy: 0.9861 - val_loss: 6.5636 - val_accuracy: 0.6210 Epoch 13/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 152 ms/s step - loss: 0.2146 accuracy: 0.9289 - val_loss: 6.7039 - val_accuracy: 0.4839 Epoch 14/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 152 ms/s step - loss: 0.2566 - accuracy: 0.9087 - val_loss: 6.6852 - val_accuracy: 0.6532 Epoch 15/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 149 ms/s step - loss: 0.0579 accuracy: 0.9840 - val_loss: 6.5971 - val_accuracy: 0.6935 Epoch 16/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 152 ms/s step - loss: 0.0414 - accuracy: 0.9866-val_loss: 6.6049 - val_accuracy: 0.7581 Epoch 17/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 146 ms/s step - loss: 0.0907 accuracy: 0.9689 - val_loss: 6.6476 - val_accuracy: 0.6452 Epoch 18/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 147 ms/s step - loss: 0.0929 - accuracy: 0.9685-val_loss: 6.6590 - val_accuracy: 0.7903 Epoch 19/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 146 ms/s step - loss: 0.0364 accuracy: 0.9935 - val_loss: 6.5915 - val_accuracy: 0.6290 Epoch 20/20 16/16 [= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =] - 2 151 ms/s step - loss: 0.1081 - accuracy: 0.9662-val_loss: 6.6541-val_accuracy: 0.6613Copy the code

Vi. Model evaluation

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(epochs)

plt.figure(figsize=(12.4))
plt.subplot(1.2.1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1.2.2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
Copy the code

In order to reflect the original VGG-16, the model parameters are not modified in this paper, but the correlation parameters in the model can be modified according to the actual situation to adapt to the actual situation so as to improve the classification effect.


Recommended Reading:

  • Depth study of 100 cases – convolution neural network (CNN) implementation mnist handwritten numeral recognition | 1 day
  • Deep learning 100 cases – convolution neural network (CNN) color image classification | 2 days
  • Depth study of 100 cases – convolution neural network (CNN) weather identification | 5 days
  • Depth study of 100 cases (VGG – 19) – convolution neural network to identify the spirit the characters in the cage | 7 days

From the column:100 Examples of Deep Learning

If you find this article helpful, remember to follow it, like it, or add it to your favorites

Data can be obtained from the reply [DL+6] in the wechat official account [K Classmate ah].