Как я могу использовать трансферное обучение для решения проблемы регрессии Keras? - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь построить CNN, используя трансферное обучение и тонкую настройку Задача состоит в том, чтобы создать CNN с Keras, получающим набор данных изображений (фотографии домов) и CSV-файл (имена и цены фотографий), и обучать CNN с этими входами. Но у меня есть проблема, которую я не могу исправить.

Это мой код:

import pandas as pd
from google.colab import drive
from sklearn.model_selection import train_test_split
from keras import applications
from keras import optimizers
from keras import backend
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Model, load_model
from keras.layers import GlobalAveragePooling2D, Dense, Flatten
from matplotlib import pyplot

drive.mount('/content/gdrive')
!unzip -n '/content/gdrive/My Drive/HOUSEPRICES.zip' >> /dev/null

data_path = 'HOUSEPRICES/'
imgs_path = data_path + "images/"
labels_path = data_path + "prices.csv"

labels = pd.read_csv(labels_path), dtype = {"prices": "float64"})

seed = 0
train_data, test_data = train_test_split(labels, test_size=0.25, random_state=seed) 
dev_data, test_data = train_test_split(test_data, test_size=0.5, random_state=seed)  

train_data = train_data.reset_index(drop=True)
dev_data = dev_data.reset_index(drop=True)
test_data = test_data.reset_index(drop=True)

datagen = ImageDataGenerator(rescale=1./255)

img_width = 320
img_height = 240  
x_col = 'image_name'          
y_col = 'prices'


batch_size = 64              
train_dataset = datagen.flow_from_dataframe(dataframe=train_data, directory=imgs_path, x_col=x_col, y_col=y_col, has_ext=True,
                                            class_mode="input", target_size=(img_width,img_height), batch_size=batch_size)
dev_dataset = datagen.flow_from_dataframe(dataframe=dev_data, directory=imgs_path, x_col=x_col, y_col=y_col, has_ext=True,
                                          class_mode="input",target_size=(img_width,img_height), batch_size=batch_size)
test_dataset = datagen.flow_from_dataframe(dataframe=test_data, directory=imgs_path, x_col=x_col, y_col=y_col, has_ext=True,
                                           class_mode="input", target_size=(img_width,img_height), batch_size=batch_size)


base_model = applications.InceptionV3(weights='imagenet', include_top=False, input_shape=(img_width,img_height,3))


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

x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Flatten()(x)
x = Dense(512, activation='relu')(x)

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

model = Model(inputs=[base_model.input], outputs=[predictions])
model.summary()   

model.compile(loss='mse',     
              optimizer=optimizers.adam(lr=1e-5),  
              metrics=['mse'])


model.fit_generator(train_dataset,
                    epochs=20,  
                    verbose=2,  
                    steps_per_epoch=len(train_data)/batch_size,
                    validation_data=dev_dataset,
                    validation_steps=len(dev_data)/batch_size)

test_loss, test_mse = model.evaluate_generator(test_dataset,                                                   steps=len(test_data)/batch_size, verbose=1)

И я получаю эту ошибку:

ValueError: вход 0 несовместим со слоем flatten_9: ожидается min_ndim = 3, найдено ndim = 2

В чем проблема с моим кодом? Возможно, я неправильно строю набор данных (изображения + числовые цены)? Или это проблема с архитектурой модели? Как я могу исправить код?

Ответы [ 3 ]

0 голосов
/ 21 апреля 2019

GlobalAveragePooling2D выполняет объединение по пространственным данным. Выходная форма (batch_size, channel). Таким образом, это можно напрямую подавать на плотный слой без необходимости выравнивания. Чтобы исправить код, удалите эту строку:

x = Flatten()(x) 

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

https://keras.io/applications/

class_mode = "input" для авто кодировщиков; именно поэтому произошла ошибка о том, что цель не имеет ту же форму, что и входные данные.

class_mode = 'other' работает, потому что y_col определен.

https://keras.io/preprocessing/image/#flow_from_dataframe

0 голосов
/ 22 апреля 2019
import pandas as pd
from google.colab import drive
from sklearn.model_selection import train_test_split
from keras import applications
from keras import optimizers
from keras import backend
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Model, load_model
from keras.layers import GlobalAveragePooling2D, Dense, Flatten
from matplotlib import pyplot

drive.mount('/content/gdrive')
!unzip -n '/content/gdrive/My Drive/HOUSEPRICES.zip' >> /dev/null

data_path = 'HOUSEPRICES/'
imgs_path = data_path + "images/"
labels_path = data_path + "prices.csv"

labels = pd.read_csv(labels_path), dtype = {"prices": "float64"})

seed = 0
train_data, test_data = train_test_split(labels, test_size=0.25, random_state=seed) 
dev_data, test_data = train_test_split(test_data, test_size=0.5, random_state=seed)  

train_data = train_data.reset_index(drop=True)
dev_data = dev_data.reset_index(drop=True)
test_data = test_data.reset_index(drop=True)

datagen = ImageDataGenerator(rescale=1./255)

img_width = 320
img_height = 240  
x_col = 'image_name'          
y_col = 'prices'


batch_size = 64              
train_dataset = datagen.flow_from_dataframe(dataframe=train_data, directory=imgs_path, x_col=x_col, y_col=y_col, has_ext=True,
                                            class_mode="other", target_size=(img_width,img_height), batch_size=batch_size)
dev_dataset = datagen.flow_from_dataframe(dataframe=dev_data, directory=imgs_path, x_col=x_col, y_col=y_col, has_ext=True,
                                          class_mode="other",target_size=(img_width,img_height), batch_size=batch_size)
test_dataset = datagen.flow_from_dataframe(dataframe=test_data, directory=imgs_path, x_col=x_col, y_col=y_col, has_ext=True,
                                           class_mode="other", target_size=(img_width,img_height), batch_size=batch_size)


base_model = applications.InceptionV3(weights='imagenet', include_top=False, input_shape=(img_width,img_height,3))


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

x = base_model.output
x = GlobalAveragePooling2D()(x)    
x = Dense(256, activation='relu')(x)
x = Dropout(0.4)(x)
x = Dense(256, activation='relu')(x)

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

model = Model(inputs=[base_model.input], outputs=[predictions])
model.summary()   

model.compile(loss='mse',     
              optimizer=optimizers.adam(lr=1e-5),  
              metrics=['mse'])


model.fit_generator(train_dataset,
                    epochs=20,  
                    verbose=2,  
                    steps_per_epoch=len(train_data)/batch_size,
                    validation_data=dev_dataset,
                    validation_steps=len(dev_data)/batch_size)

test_loss, test_mse = model.evaluate_generator(test_dataset, steps=len(test_data)/batch_size, verbose=1)
0 голосов
/ 21 апреля 2019

Flatten(), преобразует векторы более высокой размерности в 2-мерные. Если у вас уже есть двухмерный вектор, вам не нужно Flatten().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...