1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/Python_Ai_Road-eat_tensorflow2_in_30_days

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
6-1,构建模型的3种方法.md 17 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 03.12.2024 15:14 374a95e

6-1, Три способа построения модели

Можно использовать три способа для построения модели: использовать Sequential для последовательного построения модели по слоям, использовать функциональный API для создания моделей произвольной структуры, наследовать от базового класса Model для создания пользовательских моделей.

Для моделей с последовательной структурой предпочтительно использовать метод Sequential.

Если модель имеет несколько входов или выходов, либо модели требуется совместное использование весов, либо модель имеет не последовательные структуры, такие как остаточные соединения, рекомендуется использовать для создания функциональный API.

По возможности избегайте использования наследования от класса Model для построения моделей без особой необходимости, хотя этот способ и обеспечивает большую гибкость, но также увеличивает вероятность ошибок.

Ниже мы проиллюстрируем три метода создания моделей на примере задачи классификации отзывов о фильмах IMDB.

import numpy as np
import pandas as pd
import tensorflow as tf
from tqdm import tqdm
from tensorflow.keras import *

train_token_path = "./data/imdb/train_token.csv"
test_token_path = "./data/imdb/test_token.csv"

MAX_WORDS = 10000  # Мы будем рассматривать только первые 10 000 слов в наборе данных
MAX_LEN = 200  # Мы обрежем отзывы после 200 слов
BATCH_SIZE = 20

# Построение конвейера
def parse_line(line):
    t = tf.strings.split(line,"\t")
    label = tf.reshape(tf.cast(tf.strings.to_number(t[0]),tf.int32),(-1,))
    features = tf.cast(tf.strings.to_number(tf.strings.split(t[1]," ")),tf.int32)
    return (features,label)

ds_train=  tf.data.TextLineDataset(filenames = [train_token_path]) \
   .map(parse_line,num_parallel_calls = tf.data.experimental.AUTOTUNE) \
   .shuffle(buffer_size = 1000).batch(BATCH_SIZE) \
   .prefetch(tf.data.experimental.AUTOTUNE)

ds_test=  tf.data.TextLineDataset(filenames = [test_token_path]) \
   .map(parse_line,num_parallel_calls = tf.data.experimental.AUTOTUNE) \
   .shuffle(buffer_size = 1000).batch(BATCH_SIZE) \
   .prefetch(tf.data.experimental.AUTOTUNE)

1. Создание модели Sequential послойно

tf.keras.backend.clear_session()

model = models.Sequential()

model.add(layers.Embedding(MAX_WORDS,7,input_length=MAX_LEN))
model.add(layers.Conv1D(filters = 64,kernel_size = 5,activation = "relu"))
model.add(layers.MaxPool1D(2))
model.add(layers.Conv1D(filters = 32,kernel_size = 3,activation = "relu"))
model.add(layers.MaxPool1D(2))
model.add(layers.Flatten())
model.add(layers.Dense(1,activation = "sigmoid"))

model.compile(optimizer='Nadam',
            loss='binary_crossentropy',
            metrics=['accuracy',"AUC"])

model.summary()

import datetime
baselogger = callbacks.BaseLogger(stateful_metrics=["AUC"])
logdir = "./data/keras_model/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)
history = model.fit(ds_train,validation_data = ds_test,
        epochs = 6,callbacks=[baselogger,tensorboard_callback])
%matplotlib inline
%config InlineBackend.figure_format = 'svg'

import matplotlib.pyplot as plt

def plot_metric(history, metric):
    train_metrics = history.history[metric]
    val_metrics = history.history['val_'+metric]
    epochs = range(1, len(train_metrics) + 1)
    plt.plot(epochs, train_metrics, 'bo--')
    plt.plot(epochs, val_metrics, 'ro-')
    plt.title('Training and validation '+ metric)
    plt.xlabel("Epochs")
    plt.ylabel(metric)
    plt.legend(["train_"+metric, 'val_'+metric])
    plt.show()
plot_metric(history,"AUC")

2. Создание произвольной модели с помощью функционального API

tf.keras.backend.clear_session()

inputs = layers.Input(shape=[MAX_LEN])
x  = layers.Embedding(MAX_WORDS,7)(inputs)

branch1 = layers.SeparableConv1D(64,3,activation="relu")(x)
branch1 = layers.MaxPool1D(3)(branch1)
branch1 = layers.SeparableConv1D(32,3,activation="relu")(branch1)
branch1 = layers.GlobalMaxPool1D()(branch1)

branch2 = layers.SeparableConv1D(64,5,activation="relu")(x)
branch2 = layers.MaxPool1D(5)(branch2)
branch2 = layers.SeparableConv1D(32,5,activation="relu")(branch2)
branch2 = layers.GlobalMaxPool1D()(branch2)

branch3 = layers.SeparableConv1D(64,7,activation="relu")(x)
branch3 = layers.MaxPool1D(7)(branch3)
branch3 = layers.SeparableConv1D(32,7,activation="relu")(branch3)
branch3 = layers.GlobalMaxPool1D()(branch3)

concat = layers.Concatenate()([branch1,branch2,branch3])
outputs = layers.Dense(1,activation = "sigmoid")(concat)

model = models.Model(inputs = inputs,outputs = outputs)

model.compile(optimizer='Nadam',
            loss='binary_crossentropy', ```
metrics=['accuracy',"AUC"])

model.summary()

Model: "model"


Слой (тип) Выходная форма Количество параметров Соединено с

input_1 (InputLayer) [(None, 200)] 0


embedding (Embedding) (None, 200, 7) 70000 input_1[0][0]


separable_conv1d (SeparableConv) (None, 198, 64) 533 embedding[0][0]


separable_conv1d_2 (SeparableConv) (None, 196, 64) 547 embedding[0][0]


separable_conv1d_4 (SeparableConv) (None, 194, 64) 561 embedding[0][0]


max_pooling1d (MaxPooling1D) (None, 66, 64) 0 separable_conv1d[0][0]


max_pooling1d_1 (MaxPooling1D) (None, 39, 64) 0 separable_conv1d_2[0][0]


max_pooling1d_2 (MaxPooling1D) (None, 27, 64) 0 separable_conv1d_4[0][0]


separable_conv1d_1 (SeparableConv) (None, 64, 32) 2272 max_pooling1d[0][0]


separable_conv1d_3 (SeparableConv) (None, 35, 32) 2400 max_pooling1d_1[0][0]


separable_conv1d_5 (SeparableConv) (None, 21, 32) 2528 max_pooling1d_2[0][0]


global_max_pooling1d (GlobalMax) (None, 32) 0 separable_conv1d_1[0][0]


global_max_pooling1d_1 (GlobalMax) (None, 32) 0 separable_conv1d_3[0][0]


global_max_pooling1d_2 (GlobalMax) (None, 32) 0 separable_conv1d_5[0][0]


concatenate (Concatenate) (None, 96) 0 global_max_pooling1d[0][0]
global_max_pooling1d_1[0][0]
global_max_pooling1d_2[0][0]


dense (Dense) (None, 1) 97 concatenate[0][0]

Всего параметров: 78 938 Обучаемых параметров: 78 938 Необучаемых параметров: 0



```python
import datetime
logdir = "./data/keras_model/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback =
``` ```
tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)
history = model.fit(ds_train, validation_data=ds_test, epochs=6, callbacks=[tensorboard_callback])
Эпоха 1/6
1000/1000 [==============================] - 32с 32мс/шаг - потери: 0.5527 - точность: 0.6758 - AUC: 0.7731 - val_loss: 0.3646 - val_accuracy: 0.8426 - val_AUC: 0.9192
Эпоха 2/6
1000/1000 [==============================] - 24с 24мс/шаг - потери: 0.3024 - точность: 0.8737 - AUC: 0.9444 - val_loss: 0.3281 - val_accuracy: 0.8644 - val_AUC: 0.9350
Эпоха 3/6
1000/1000 [==============================] - 24с 24мс/шаг - потери: 0.2158 - точность: 0.9159 - AUC: 0.9715 - val_loss: 0.3461 - val_accuracy: 0.8666 - val_AUC: 0.9363
Эпоха 4/6
1000/1000 [==============================] - 24с 24мс/шаг - потери: 0.1492 - точность: 0.9464 - AUC: 0.9859 - val_loss: 0.4017 - val_accuracy: 0.8568 - val_AUC: 0.9311
Эпоха 5/6
1000/1000 [==============================] - 24с 24мс/шаг - потери: 0.0944 - точность: 0.9696 - AUC: 0.9939 - val_loss: 0.4998 - val_accuracy: 0.8550 - val_AUC: 0.9233
Эпоха 6/6
1000/1000 [==============================] - 26с 26мс/шаг - потери: 0.0526 - точность: 0.9865 - AUC: 0.9977 - val_loss: 0.6463 - val_accuracy: 0.8462 - val_AUC: 0.9138
plot_metric(history, "AUC")

Три, Model子类化创建自定义模型

# 先自定义一个残差模块,为自定义Layer

class ResBlock(layers.Layer):
    def __init__(self, kernel_size, **kwargs):
        super(ResBlock, self).__init__(**kwargs)
        self.kernel_size = kernel_size
    
    def build(self, input_shape):
        self.conv1 = layers.Conv1D(filters=64, kernel_size=self.kernel_size,
                                 activation="relu", padding="same")
        self.conv2 = layers.Conv1D(filters=32, kernel_size=self.kernel_size,
                                 activation="relu", padding="same")
        self.conv3 = layers.Conv1D(filters=input_shape[-1],
                                 kernel_size=self.kernel_size, activation="relu", padding="same")
        self.maxpool = layers.MaxPool1D(2)
        super(ResBlock,self).build(input_shape) # 相当于设置self.built = True
    
    def call(self, inputs):
        x = self.conv1(inputs)
        x = self.conv2(x)
        x = self.conv3(x)
        x = layers.Add()([inputs, x])
        x = self.maxpool(x)
        return x
    
    # 如果要让自定义的Layer通过Functional API 组合成模型时可以序列化,需要自定义get_config方法。
    def get_config(self):  
        config = super(ResBlock, self).get_config()
        config.update({'kernel_size': self.kernel_size})
        return config
# 测试ResBlock
resblock = ResBlock(kernel_size=3)
resblock.build(input_shape=(None, 200, 7))
resblock.compute_output_shape(input_shape=(None, 200, 7))
TensorShape([None, 100, 7])
# 自定义模型,实际上也可以使用Sequential或者FunctionalAPI

class ImdbModel(models.Model):
    def __init__(self):
        super(ImdbModel, self).__init__()
        
    def build(self,input_shape):
        self.embedding = layers.Embedding(MAX_WORDS, 7)
        self.block1 = ResBlock(7)
        self.block2 = ResBlock(5)
        self.dense = layers.Dense(1,activation="sigmoid")
        super(ImdbModel,self).build(input_shape)
    
    def call(self, x):
        x = self.embedding(x)
        x = self.block1(x)
        x = self.block2(x)
        x = layers.Flatten()(x)
        x = self.dense(x)
        return(x)
tf.keras.backend.clear_session()

model = ImdbModel()
model.build(input_shape =(None,200))
model.summary()

model.compile(optimizer='Nadam',
            loss='binary_crossentropy',
            metrics=['accuracy',"AUC"])
Model: "imdb_model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        multiple                  70000     
_________________________________________________________________
res_block (ResBlock)         multiple                  19143
``` ```
res_block_1 (ResBlock)       multiple                  13703     
_________________________________________________________________
dense (Dense)                multiple                  351       
=================================================================
Всего параметров: 103,197
Обучаемые параметры: 103,197
Необучаемые параметры: 0
_________________________________________________________________

import datetime

logdir = "./tflogs/keras_model/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)
history = model.fit(ds_train,validation_data = ds_test,
                    epochs = 6,callbacks=[tensorboard_callback])
Эпоха 1/6
1000/1000 [==============================] - 47с 47мс/шаг - потеря: 0.5629 - точность: 0.6618 - AUC: 0.7548 - val_loss: 0.3422 - val_accuracy: 0.8510 - val_AUC: 0.9286
Эпоха 2/6
1000/1000 [==============================] - 43с 43мс/шаг - потеря: 0.2648 - точность: 0.8903 - AUC: 0.9576 - val_loss: 0.3276 - val_accuracy: 0.8650 - val_AUC: 0.9410
Эпоха 3/6
1000/1000 [==============================] - 42с 42мс/шаг - потеря: 0.1573 - точность: 0.9439 - AUC: 0.9846 - val_loss: 0.3861 - val_accuracy: 0.8682 - val_AUC: 0.9390
Эпоха 4/6
1000/1000 [==============================] - 42с 42мс/шаг - потеря: 0.0849 - точность: 0.9706 - AUC: 0.9950 - val_loss: 0.5324 - val_accuracy: 0.8616 - val_AUC: 0.9292
Эпоха 5/6
1000/1000 [==============================] - 43с 43мс/шаг - потеря: 0.0393 - точность: 0.9876 - AUC: 0.9986 - val_loss: 0.7693 - val_accuracy: 0.8566 - val_AUC: 0.9132
Эпоха 6/6
1000/1000 [==============================] - 44с 44мс/шаг - потеря: 0.0222 - точность: 0.9926 - AUC: 0.9994 - val_loss: 0.9328 - val_accuracy: 0.8584 - val_AUC: 0.9052
plot_metric(history,"AUC")

Если у вас есть какие-либо вопросы по содержанию этой книги, пожалуйста, оставьте комментарий в нашем публичном аккаунте «Алгоритмная кухня». Автор ответит вам, когда у него будет время.

Вы также можете ответить ключевым словом join на заднем плане публичного аккаунта, чтобы присоединиться к группе читателей и обсудить с ними.

![Алгоритмная кухня QR-код.jpg](./data/Алгоритмная кухня QR-код.jpg)


Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/Python_Ai_Road-eat_tensorflow2_in_30_days.git
git@api.gitlife.ru:oschina-mirror/Python_Ai_Road-eat_tensorflow2_in_30_days.git
oschina-mirror
Python_Ai_Road-eat_tensorflow2_in_30_days
Python_Ai_Road-eat_tensorflow2_in_30_days
master