【问题标题】:Preprocessing for Transfer Learning Model with an Inception Network带有初始网络的迁移学习模型的预处理
【发布时间】:2021-11-30 16:58:30
【问题描述】:

我正在尝试使用 Inception Network 作为基础来构建图像分类模型。这是一个简单的二元分类模型。

我的图像可以在一个大目录中的许多较小目录中找到。它们每个都有自己的“图像 ID”,这就是它们的命名方式。除此之外,我还有一些 tsv 文件,其中包含这些图像 ID 和相应的标签(“正”或“负”)。

当我训练模型时,我发现我的准确率在没有太大进展的情况下波动。我想知道我准备数据集的方式是否有问题。为此,我编写了一些函数。

在我开始使用这些函数之前,下面给出了我是如何定义我的模型的,

base_model = InceptionV3(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dropout(0.4)(x)
predictions = Dense(2, activation='sigmoid')(x)
model = Model(inputs=base_model.input, outputs=predictions)

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

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

这些是我为准备数据而编写的函数,

def vectorize_img(img_path):
  img = load_img(img_path, target_size=(224, 224)) #size is 224,224 by default
  x = img_to_array(img) #change to np array
  x = preprocess_input(x) #make input confirm to InceptionV3 input format
  return x

def prepare_features(base_dir, limit):
  features_dict = dict()
  for dir1 in os.listdir(base_dir):
      for dir2 in os.listdir(base_dir + dir1):
          for file in os.listdir(base_dir + dir1 + '/' + dir2):
            if len(features_dict) < limit:
              try:
                img_path = base_dir + dir1 + '/' + dir2 + '/' + file
                x = vectorize_img(img_path)
        
                name_id = file.split('.')[0] #take the file name and use as id in dict
                features_dict[name_id] = x
              except Exception as e:
                print(e)
                pass

  return features_dict

def prepare_data(file_path, features_dict):
  inputs = []
  labels = []
  df = pd.read_csv(file_path, sep='\t')
  df = df[['image_id', 'label_text_image']]
  df['class'] = df[['image_id', 'label_text_image']].apply(lambda x: 1 if x['label_text_image'] == 'Positive' else 0, axis = 1)

  for index, row in df.iterrows():
    try:
      inputs.append(features_dict[row['image_id']])
      labels.append(row['class'])
    except:
      pass

  return np.asarray(inputs), tf.one_hot(np.asarray(labels), depth=2)

然后调用这些函数来准备我的数据集,

features_dict = prepare_features('/path/to/img/dir', 8000)

x_train, y_train = prepare_data('/path/to/train/tsv', features_dict)
x_dev, y_dev = prepare_data('/path/to/dev/tsv', features_dict)
x_test, y_test = prepare_data('/path/to/test/tsv', features_dict)

最后,模型训练完毕,

EPOCHS = 50
BATCH_SIZE = 32
STEPS_PER_EPOCH = 1
history = model.fit(x=x_train, y=y_train, validation_data=(x_dev, y_dev), epochs=EPOCHS, steps_per_epoch=STEPS_PER_EPOCH, batch_size=BATCH_SIZE)

model.evaluate(x=x_test, y=y_test, batch_size=BATCH_SIZE)

我是不是做错了什么?

这是我的模型实现的结果,

Epoch 1/50
1/1 [==============================] - 158s 158s/step - loss: 0.8298 - accuracy: 0.5000 - val_loss: 0.7432 - val_accuracy: 0.5227
Epoch 2/50
1/1 [==============================] - 113s 113s/step - loss: 0.7775 - accuracy: 0.4688 - val_loss: 0.8225 - val_accuracy: 0.5153
Epoch 3/50
1/1 [==============================] - 113s 113s/step - loss: 0.7663 - accuracy: 0.5625 - val_loss: 0.8431 - val_accuracy: 0.5174
Epoch 4/50
1/1 [==============================] - 156s 156s/step - loss: 1.1292 - accuracy: 0.5312 - val_loss: 0.7763 - val_accuracy: 0.5227
Epoch 5/50
1/1 [==============================] - 114s 114s/step - loss: 0.7452 - accuracy: 0.5312 - val_loss: 0.7332 - val_accuracy: 0.5448
Epoch 6/50
1/1 [==============================] - 156s 156s/step - loss: 0.7884 - accuracy: 0.5312 - val_loss: 0.7072 - val_accuracy: 0.5606
Epoch 7/50
1/1 [==============================] - 114s 114s/step - loss: 0.7856 - accuracy: 0.5312 - val_loss: 0.7195 - val_accuracy: 0.5764
Epoch 8/50
1/1 [==============================] - 156s 156s/step - loss: 0.9203 - accuracy: 0.5312 - val_loss: 0.7348 - val_accuracy: 0.5616
Epoch 9/50
1/1 [==============================] - 156s 156s/step - loss: 0.8639 - accuracy: 0.4062 - val_loss: 0.7275 - val_accuracy: 0.5690
Epoch 10/50
1/1 [==============================] - 156s 156s/step - loss: 0.6170 - accuracy: 0.7188 - val_loss: 0.7125 - val_accuracy: 0.5880
Epoch 11/50
1/1 [==============================] - 156s 156s/step - loss: 0.5756 - accuracy: 0.7188 - val_loss: 0.6979 - val_accuracy: 0.6017
Epoch 12/50
1/1 [==============================] - 113s 113s/step - loss: 0.9976 - accuracy: 0.4375 - val_loss: 0.6834 - val_accuracy: 0.5933
Epoch 13/50
1/1 [==============================] - 156s 156s/step - loss: 0.7025 - accuracy: 0.5938 - val_loss: 0.6863 - val_accuracy: 0.5838

【问题讨论】:

标签: python keras conv-neural-network tensorflow2.0 transfer-learning


【解决方案1】:

你提到它是一个二元分类,因此标签是{0,1}。在这种情况下,您的模型输出应该是

predictions = Dense(2, activation='softmax')(x)

带有分类标签[0,1] or [1,0]

predictions = Dense(1, activation='sigmoid')(x)

带有二进制标签1 or 0 但是您将输出 2 与sigmoid 一起使用,即predictions = Dense(2, activation='sigmoid')(x)

【讨论】:

  • 好收获。不过,我的准确性似乎仍然波动很大。我觉得可能还有其他问题?这就是我的标签的样子:tf.Tensor([0.], shape=(1,), dtype=float32)。这样可以吗?
  • 如果你的输出是Dense(1, activation='sigmoid')(x) 那么它很好。如果有帮助,您可以尝试降低 LR。您也没有在代码中提到model.compile。您可以编辑具有波动准确性结果的问题吗?
  • 我已经在问题中包含了模型的性能。是的,我会尝试调整学习率。
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 2018-11-30
  • 2021-01-17
  • 1970-01-01
相关资源
最近更新 更多