質問編集履歴
2
修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -134,7 +134,71 @@
|
|
134
134
|
|
135
135
|
|
136
136
|
|
137
|
+
```
|
138
|
+
|
139
|
+
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
140
|
+
|
141
|
+
from tensorflow.keras.utils import to_categorical
|
142
|
+
|
143
|
+
from numpy import array
|
144
|
+
|
145
|
+
#画像と出力単語を紐づける関数
|
146
|
+
|
147
|
+
def create_sequences(tokenizer, max_length, descriptions, photos):
|
148
|
+
|
149
|
+
X1, X2, y = list(), list(), list()#X1が入力画像、X2が入力語、yがX1とX2に対応する出力語
|
150
|
+
|
151
|
+
#各画像名でループ
|
152
|
+
|
153
|
+
for key, desc_list in descriptions.items():
|
154
|
+
|
155
|
+
#各画像のキャプションでループ
|
156
|
+
|
157
|
+
for desc in desc_list:
|
158
|
+
|
137
|
-
#
|
159
|
+
#シーケンスをエンコードする
|
160
|
+
|
161
|
+
seq = tokenizer.texts_to_sequences([desc])[0]
|
162
|
+
|
163
|
+
#1つのシーケンスを複数のX、Yペアに分割する
|
164
|
+
|
165
|
+
for i in range(1, len(seq)):
|
166
|
+
|
167
|
+
#入力と出力のペアに分割する
|
168
|
+
|
169
|
+
in_seq, out_seq = seq[:i], seq[i]
|
170
|
+
|
171
|
+
#行列のサイズを最大の単語数に合わせる
|
172
|
+
|
173
|
+
in_seq = pad_sequences([in_seq], maxlen=max_length)[0]
|
174
|
+
|
175
|
+
#出力シーケンス
|
176
|
+
|
177
|
+
out_seq = to_categorical([out_seq], num_classes=vocab_size)[0]
|
178
|
+
|
179
|
+
#全てをarrayに格納
|
180
|
+
|
181
|
+
X1.append(photos[key][0])
|
182
|
+
|
183
|
+
X2.append(in_seq)
|
184
|
+
|
185
|
+
y.append(out_seq)
|
186
|
+
|
187
|
+
return array(X1), array(X2), array(y)
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
#トレーニングデータの入力画像、入力語、出力語を紐付ける
|
192
|
+
|
193
|
+
X1train, X2train, ytrain = create_sequences(tokenizer, max_length, train_descriptions, train_features)
|
194
|
+
|
195
|
+
print(X1train)
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
#バリデーションデータの入力画像、入力語、出力語を紐付ける
|
200
|
+
|
201
|
+
X1val, X2val, yval = create_sequences(tokenizer, max_length, val_descriptions, val_features)
|
138
202
|
|
139
203
|
from tensorflow.keras.layers import Input,Dense,LSTM,Embedding,Dropout
|
140
204
|
|
@@ -142,11 +206,11 @@
|
|
142
206
|
|
143
207
|
|
144
208
|
|
145
|
-
モデルを定義する関数
|
209
|
+
#モデルを定義する関数
|
146
210
|
|
147
211
|
def define_model(vocab_size, max_length):
|
148
212
|
|
149
|
-
画像の特徴を入力するレイヤ
|
213
|
+
#画像の特徴を入力するレイヤ
|
150
214
|
|
151
215
|
inputs1 = Input(shape=(4096,))
|
152
216
|
|
@@ -154,7 +218,7 @@
|
|
154
218
|
|
155
219
|
fe2 = Dense(256, activation='relu')(fe1)
|
156
220
|
|
157
|
-
文章を入力するレイヤ
|
221
|
+
#文章を入力するレイヤ
|
158
222
|
|
159
223
|
inputs2 = Input(shape=(max_length,))
|
160
224
|
|
@@ -164,7 +228,7 @@
|
|
164
228
|
|
165
229
|
se3 = LSTM(256)(se2)
|
166
230
|
|
167
|
-
上の二つの出力を統合する部分
|
231
|
+
#上の二つの出力を統合する部分
|
168
232
|
|
169
233
|
decoder1 = add([fe2, se3])
|
170
234
|
|
@@ -172,10 +236,32 @@
|
|
172
236
|
|
173
237
|
outputs = Dense(vocab_size, activation='softmax')(decoder2)
|
174
238
|
|
175
|
-
モデルの定義.二つを入力にとって一つを出力する形になる
|
239
|
+
#モデルの定義.二つを入力にとって一つを出力する形になる
|
176
240
|
|
177
241
|
model = Model(inputs=[inputs1, inputs2], outputs=outputs)
|
178
242
|
|
179
243
|
model.compile(loss='categorical_crossentropy', optimizer='adam')
|
180
244
|
|
181
245
|
return model
|
246
|
+
|
247
|
+
|
248
|
+
|
249
|
+
from tensorflow.keras.callbacks import ModelCheckpoint
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
#モデルの定義
|
254
|
+
|
255
|
+
model = define_model(vocab_size, max_length)
|
256
|
+
|
257
|
+
#コールバックを定義する
|
258
|
+
|
259
|
+
filepath = 'model-ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5'
|
260
|
+
|
261
|
+
checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='min')
|
262
|
+
|
263
|
+
#学習
|
264
|
+
|
265
|
+
model.fit([X1train, X2train], ytrain, epochs=10, verbose=2, callbacks=[checkpoint], validation_data=([X1val, X2val], yval))
|
266
|
+
|
267
|
+
```
|
1
表記方法のミスで訂正
test
CHANGED
File without changes
|
test
CHANGED
@@ -142,7 +142,7 @@
|
|
142
142
|
|
143
143
|
|
144
144
|
|
145
|
-
|
145
|
+
モデルを定義する関数
|
146
146
|
|
147
147
|
def define_model(vocab_size, max_length):
|
148
148
|
|