Saya telah menjalankan model dasar dengan akurasi yang baik dan sekarang saya ingin memuat bobot ini dan menggunakannya untuk model dengan beberapa lapisan tambahan dan kemudian untuk penyetelan hyperparameter.

Pertama saya membangun model baru ini

  input_tensor = Input(shape=train_generator.image_shape)

  base_model = applications.ResNet152(weights='imagenet', include_top=False, input_tensor=input_tensor)

  for layer in base_model.layers[:]:
    layer.trainable = False 

  x = Flatten()(base_model.output)
  x = Dense(1024, kernel_regularizer=tf.keras.regularizers.L2(l2=0.01), 
          kernel_initializer=tf.keras.initializers.HeNormal(), kernel_constraint=tf.keras.constraints.UnitNorm(axis=0))(x)
  x = LeakyReLU()(x)
  x = BatchNormalization()(x)
  x = Dropout(rate=0.1)(x)
  x = Dense(512, kernel_regularizer=tf.keras.regularizers.L2(l2=0.01), 
          kernel_initializer=tf.keras.initializers.HeNormal(), kernel_constraint=tf.keras.constraints.UnitNorm(axis=0))(x)
  x = LeakyReLU()(x)
  x = BatchNormalization()(x)
  
  predictions = Dense(num_classes, activation= 'softmax')(x)
  model = Model(inputs = base_model.input, outputs = predictions)

Kemudian saya mengkompilasinya karena itu diperlukan pada tahap ini karena saya harus menjalankan model yang sesuai dengan input dummy sebelum saya memuat bobot. (Saya pikir, saya telah mencoba menempatkan blok kode ini dalam banyak urutan berbeda untuk membuatnya berfungsi, tetapi saya selalu gagal)

opt = tfa.optimizers.LazyAdam(lr=0.000074)

model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=opt,
    metrics=['accuracy']
    )

dummy_input = tf.random.uniform([32, 224, 224, 3]) 
dummy_label = tf.random.uniform([32,]) 
hist = model.fit(dummy_input, dummy_label)

Kemudian saya memuat bobot untuk model dasar:

base_model.load_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights2.h5', by_name=True)

Kemudian saya memuat bobot untuk pengoptimal:

import pickle
with open("/content/drive/MyDrive/weight_values2optimizer.pkl", "rb") as f: 
  weights = pickle.load(f) 
opt = model.optimizer.set_weights(weights) 

Ini menghasilkan kesalahan berikut:

ValueError: You called `set_weights(weights)` on optimizer LazyAdam 
with a  weight list of length 1245, 
but the optimizer was expecting 13 weights. 
Provided weights: [63504, array([[[[ 0.00000000e+00, -5.74126025e-04...

Adakah yang punya ide tentang bagaimana menyelesaikan ini?

Jika Anda memiliki solusi dengan Adam alih-alih LazyAdam, itu juga bagus. (Saya tidak tahu apakah itu akan membuat perbedaan)

Edit: Saya telah mencoba banyak hal baru beberapa hari terakhir tetapi tidak ada yang berhasil. Berikut adalah seluruh kode di mana saya berdiri sekarang. Ini mencakup bagian di mana saya menyimpan dan bagian di mana saya memuat.

import tarfile
my_tar2 = tarfile.open('test.tgz')
my_tar2.extractall('test') # specify which folder to extract to
my_tar2.close()

import zipfile
with zipfile.ZipFile("/content/tot_train_bremoved2.zip", 'r') as zip_ref:
    zip_ref.extractall("/content/train/")

import pandas as pd   

train_info = pd.read_csv("/content/drive/MyDrive/train_info.csv")
test_info = pd.read_csv("/content/drive/MyDrive/test_info.csv")
train_folder = "/content/train"
test_folder = "/content/test/test"

import tensorflow as tf
import tensorflow.keras as keras

from keras.layers import Input, Lambda, Dense, Flatten, BatchNormalization, Dropout, PReLU, GlobalAveragePooling2D, LeakyReLU, MaxPooling2D
from keras.models import Model
from tensorflow.keras.applications.resnet_v2 import ResNet152V2, preprocess_input
from keras import applications

from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator
from keras.losses import sparse_categorical_crossentropy

from keras.callbacks import ReduceLROnPlateau, ModelCheckpoint, EarlyStopping, TensorBoard

import tensorflow_addons as tfa

from sklearn.metrics import confusion_matrix
import numpy as np
import matplotlib.pyplot as plt

num_classes = 423
epochs = 20
batch_size = 32
img_height = 224
img_width = 224
IMAGE_SIZE = [img_height, img_width]

_train_generator = ImageDataGenerator(
        rotation_range=180,
        zoom_range=0.2,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.3,
        horizontal_flip=True,
        vertical_flip=True,
        preprocessing_function=preprocess_input)


_val_generator = ImageDataGenerator(
        preprocessing_function=preprocess_input)

train_generator = _train_generator.flow_from_dataframe(dataframe = train_info, 
directory = train_folder, x_col = "filename", 
y_col = "artist", seed = 42,
batch_size = batch_size, shuffle = True, 
class_mode="sparse", target_size = IMAGE_SIZE)

valid_generator = _val_generator.flow_from_dataframe(dataframe = test_info, 
directory = test_folder, x_col = "filename", 
y_col = "artist", seed = 42,
batch_size = batch_size, shuffle = True, 
class_mode="sparse", target_size = IMAGE_SIZE)

def get_uncompiled_model():
   
  input_tensor = Input(shape=train_generator.image_shape)

  base_model = applications.ResNet152(weights='imagenet', include_top=False, input_tensor=input_tensor)

  for layer in base_model.layers[:]:
    layer.trainable = True

  x = Flatten()(base_model.output)
  
  predictions = Dense(num_classes, activation= 'softmax')(x)
  model = Model(inputs = base_model.input, outputs = predictions)

  return model

opt = keras.optimizers.Adam(lr=0.000074)

def get_compiled_model():
    model = get_uncompiled_model()
    model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=opt,
    metrics=['accuracy']
    )
    return model

earlyStopping = EarlyStopping(monitor='val_loss', patience=5, verbose=0, mode='min')

reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, verbose=1, min_delta=1e-4, mode='min')

model = get_compiled_model()

from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

model.fit(
  train_generator,
  validation_data=valid_generator,
  epochs=epochs,
  verbose = 1,
  steps_per_epoch=len_train // batch_size,
  validation_steps=len_test // batch_size,
  callbacks=[earlyStopping, reduce_lr]
)

import keras.backend as K
import pickle

model.save_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights5.h5')
symbolic_weights = getattr(model.optimizer, 'weights')
weight_values = K.batch_get_value(symbolic_weights)
with open('/content/drive/MyDrive/MODELS_SAVED/optimizer3.pkl', 'wb') as f:
    pickle.dump(weight_values, f)

#Here i am building the new model and its from here i am having problems

  input_tensor = Input(shape=train_generator.image_shape)

  base_model = applications.ResNet152(weights='imagenet', include_top=False, input_tensor=input_tensor)

  for layer in base_model.layers[:]:
    layer.trainable = False 

  x = Flatten()(base_model.output)
 
  x = Dense(512, kernel_regularizer=tf.keras.regularizers.L2(l2=0.01), 
          kernel_initializer=tf.keras.initializers.HeNormal(), 
          kernel_constraint=tf.keras.constraints.UnitNorm(axis=0))(x)
  x = LeakyReLU()(x)
  x = BatchNormalization()(x)
  
  predictions = Dense(num_classes, activation= 'softmax')(x)
  model = Model(inputs = base_model.input, outputs = predictions)

model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer='adam',
    metrics=['accuracy']
    )

base_model.load_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights5.h5', by_name=True)

with open('/content/drive/MyDrive/MODELS_SAVED/optimizer3.pkl', 'rb') as f:
    weight_values = pickle.load(f)
model.optimizer.set_weights(weight_values)

from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

epochs = 2

model.fit(
  train_generator,
  validation_data=valid_generator,
  epochs=epochs,
  steps_per_epoch=len_train // batch_size,
  validation_steps=len_test // batch_size,
  verbose = 1,
  callbacks=[earlyStopping, reduce_lr]
)


Sekarang saya mendapatkan kesalahan berikut menjalankan blok kode ini (yang di atas dalam kode lengkap tepat sebelum model.fit):

with open('/content/drive/MyDrive/MODELS_SAVED/optimizer3.pkl', 'rb') as f:
    weight_values = pickle.load(f)
model.optimizer.set_weights(weight_values)
ValueError: You called `set_weights(weights)` on optimizer Adam with a  weight list of length 1245, but the optimizer was expecting 13 weights. Provided weights: [11907, array([[[[ 0.00000000e+00, -8.27514916e-04...

Yang saya coba lakukan adalah menyimpan bobot untuk model dan pengoptimal dan kemudian membangun model baru di mana saya menambahkan beberapa lapisan dan memuat bobot dari dasar model dan bobot dari pengoptimal.

2
JKnecht 14 Desember 2020, 10:33

3 jawaban

Jawaban Terbaik

Kedua model memiliki arsitektur yang berbeda sehingga bobot yang satu tidak dapat dimuat ke yang lain, terlepas dari itu mereka mewarisi model dasar yang sama. Saya pikir ini adalah kasus sederhana untuk menyempurnakan model (model tersimpan dalam kasus Anda).

Yang harus Anda lakukan adalah mengubah cara membuat model baru, yaitu daripada memuat model resnet asli sebagai model dasar dengan include_top = False, Anda harus mencoba memuat model yang disimpan dan mengimplementasikan include_top Anda sendiri. Ini dapat dilakukan sebagai:

for layer in saved_model.layers[:]:
    layer.trainable = False 

  x = Flatten()(saved_model.layers[-2].output)

Di sini kuncinya adalah saved_model.layers[-2].output yang berarti keluaran dari lapisan kedua terakhir.

Semoga membantu, jika tidak tolong jelaskan keraguan Anda atau beri tahu saya apa yang saya lewatkan.

4
Prashant Gupta 22 Desember 2020, 01:31

Silakan merujuk ke buku catatan berikut: https://colab.research.google.com/drive/1j_zLqG1zUMi6UYPdc6gwL4zUMi6UYPdc6g berbagi

  1. {save,load}_bobot pada model menyertakan bobot pengoptimal. Itu akan menjadi cara yang lebih disukai untuk menginisialisasi bobot pengoptimal.

  2. Anda dapat menyalin pengoptimal dari satu model ke model lainnya.

  3. Alasan Anda mendapatkan kesalahan di atas adalah karena pengoptimal tidak mengalokasikan bobotnya hingga pelatihan dimulai; Jika Anda benar-benar ingin melakukannya secara manual, cukup picu model.fit() untuk 1 epoch 1 datapoint, lalu muat data secara manual.

Anda dapat mengganti

base_model.load_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights5.h5', by_name=True)

with open('/content/drive/MyDrive/MODELS_SAVED/optimizer3.pkl', 'rb') as f:
    weight_values = pickle.load(f)
model.optimizer.set_weights(weight_values)

Dengan:

base_model.load_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights5.h5', by_name=True)

model.optimizer = base_model.optimizer
0
Pedro Marques 17 Desember 2020, 21:26

Setelah menyimpan bobot model pertama dengan model.save_weights('name.h5'), Anda harus membuat model kedua, persis seperti yang pertama, sebut saja model2. Kemudian muat bobot yang Anda simpan sebelumnya ke dalamnya. Kode harus model2.load_weights('name.h5'). Lihat model.summary() untuk melihat nama dan nomor layer model pertama. Untuk setiap lapisan, Anda perlu mendefinisikan variabel dan menambahkan bobot tersebut (dan juga bias) ke variabel tersebut dengan metode yang disebut get_weights() . Berikut ini contohnya:

x1 = model2.layers[1].get_weights()

Di sini, saya menempatkan bobot dan bias dari lapisan pertama (yang di saya adalah lapisan konvolusi) dalam variabel x1.

x1[0] adalah daftar bobot lapisan #1.

x1[1] adalah daftar bias dari layer #1.

0
Sara 23 Desember 2020, 05:38