Posting ini tampaknya menunjukkan bahwa apa yang ingin saya capai tidak mungkin. Namun, saya tidak yakin dengan ini - mengingat apa yang telah saya lakukan, saya tidak melihat mengapa apa yang ingin saya lakukan tidak dapat dicapai ...
Saya memiliki dua dataset gambar di mana satu memiliki gambar bentuk (480, 720, 3) sementara yang lain memiliki gambar bentuk (540, 960, 3).
Saya menginisialisasi model menggunakan kode berikut:
input = Input(shape=(480, 720, 3), name='image_input')
initial_model = VGG16(weights='imagenet', include_top=False)
for layer in initial_model.layers:
layer.trainable = False
x = Flatten()(initial_model(input))
x = Dense(1000, activation='relu')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Dense(1000, activation='relu')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Dense(14, activation='linear')(x)
model = Model(inputs=input, outputs=x)
model.compile(loss='mse', optimizer='adam', metrics=['mae'])
Sekarang saya telah melatih model ini pada dataset sebelumnya, saya ingin mematikan lapisan tensor input dan menambahkan model dengan tensor input baru dengan bentuk yang sesuai dengan dimensi gambar dari dataset yang terakhir.
model = load_model('path/to/my/trained/model.h5')
old_input = model.pop(0)
new_input = Input(shape=(540, 960, 3), name='image_input')
x = model(new_input)
m = Model(inputs=new_input, outputs=x)
m.save('transfer_model.h5')
yang menghasilkan kesalahan ini:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/aicg2/.local/lib/python2.7/site-packages/keras/engine/topology.py", line 2506, in save
save_model(self, filepath, overwrite, include_optimizer)
File "/home/aicg2/.local/lib/python2.7/site-packages/keras/models.py", line 106, in save_model
'config': model.get_config()
File "/home/aicg2/.local/lib/python2.7/site-packages/keras/engine/topology.py", line 2322, in get_config
layer_config = layer.get_config()
File "/home/aicg2/.local/lib/python2.7/site-packages/keras/engine/topology.py", line 2370, in get_config
new_node_index = node_conversion_map[node_key]
KeyError: u'image_input_ib-0'
Dalam posting yang saya tautkan, maz menyatakan bahwa ada ketidakcocokan dimensi yang mencegah perubahan lapisan input model - jika ini yang terjadi, lalu bagaimana saya meletakkan (480, 720, 3) lapisan input di depan dari model VGG16 yang mengharapkan (224, 224, 3) gambar?
Saya pikir masalah yang lebih mungkin adalah bahwa keluaran model lama saya mengharapkan sesuatu yang berbeda dari apa yang saya berikan berdasarkan apa yang dikatakan fchollet dalam posting ini . Saya bingung secara sintaksis, tetapi saya percaya seluruh x = Layer()(x)
segmen sedang membangun sepotong demi sepotong dari input-> output dan hanya melemparkan input yang berbeda di depan adalah merusaknya.
Aku benar-benar tidak tahu ...
Dapatkah seseorang tolong beri tahu saya bagaimana mencapai apa yang saya coba lakukan atau, jika tidak mungkin, jelaskan kepada saya mengapa tidak?
Jawaban:
Anda dapat melakukan ini dengan membuat instance model VGG16 baru dengan bentuk input baru
new_shape
dan menyalin semua bobot layer. Kode ini kira-kirasumber
Traceback (most recent call last): File "predict_video11.py", line 67, in <module> new_layer.set_weights(layer.get_weights()) File "/usr/local/lib/python2.7/dist-packages/keras/engine/base_layer.py", line 1057, in set_weights 'provided weight shape ' + str(w.shape)) ValueError: Layer weight shape (3, 3, 33, 64) not compatible with provided weight shape (3, 3, 9, 64)
dan itu adalah lapisan Input jadi gunakan[2:]
?Lebar dan tinggi keluaran dari dimensi keluaran VGGnet adalah bagian tetap dari lebar dan tinggi masukan karena satu-satunya lapisan yang mengubah dimensi tersebut adalah lapisan penyatuan. Jumlah saluran dalam output ditetapkan ke jumlah filter di lapisan convolutional terakhir. Lapisan rata akan membentuk kembali ini untuk mendapatkan satu dimensi dengan bentuk:
((input_width * x) * (input_height * x) * channels)
di mana x adalah beberapa desimal <1.
Poin utama adalah bahwa bentuk input ke lapisan padat tergantung pada lebar dan tinggi input ke seluruh model. Input bentuk ke lapisan padat tidak dapat berubah karena ini berarti menambah atau menghapus node dari jaringan saraf.
Salah satu cara untuk menghindari hal ini adalah dengan menggunakan lapisan pengumpulan global daripada lapisan rata (biasanya GlobalAveragePooling2D) ini akan menemukan rata-rata per saluran menyebabkan bentuk input ke lapisan Padat hanya menjadi
(channels,)
yang tidak tergantung pada bentuk input untuk seluruh model.Setelah ini dilakukan, tidak ada lapisan dalam jaringan yang bergantung pada lebar dan tinggi input sehingga lapisan input dapat diubah dengan sesuatu seperti
sumber
model.layers[0] = input_layer
tidak bekerja untuk saya di TF 2.1. Tidak ada kesalahan, tetapi layer sebenarnya tidak diganti. Sepertinya menyalin bobot mungkin lebih kuat (lihat jawaban lain).Berikut adalah solusi lain, tidak spesifik untuk model VGG.
Perhatikan, bahwa bobot lapisan padat tidak dapat disalin (dan karenanya akan diinisialisasi baru). Ini masuk akal, karena bentuk bobotnya berbeda dengan model lama dan baru.
sumber
Ini seharusnya cukup mudah
kerassurgeon
. Pertama, Anda perlu menginstal perpustakaan; tergantung pada apakah Anda menggunakan Keras melalui TensorFlow (dengan tf 2.0 ke atas) atau Keras sebagai pustaka yang terpisah, perlu diinstal dengan cara yang berbeda.Untuk Keras di TF:
pip install tfkerassurgeon
( https://github.com/Raukk/tf-keras-surgeon ). Untuk mandiri mandiri:pip install kerassurgeon
( https://github.com/BenWhetton/keras-surgeon )Untuk mengganti input (misalnya dengan TF 2.0; kode yang saat ini belum diuji):
sumber
@ gebbissimo menjawab bekerja untuk saya di TF2 dengan hanya adaptasi kecil yang saya bagikan di bawah ini dalam satu fungsi:
sumber
Ini cara saya mengubah ukuran input dalam model Keras. Saya memiliki dua model CNN, satu dengan ukuran input [Tidak ada, Tidak ada, 3] sementara yang lain memiliki ukuran input [512,512,3]. Kedua model memiliki bobot yang sama. Dengan menggunakan set_weights (model.get_weights ()), bobot model 1 dapat ditransfer ke model 2
sumber