使用 InceptionV3 处理灰度图像
Using InceptionV3 for greyscale images
我正在尝试使用迁移训练解决图像分类问题。我有一个 EEG 信号频谱图数据集。我想在此数据集上训练 InceptionV3 的最后几层。然而,InceptionV3 只采用三层图像,但我想在灰度图像上训练它,因为图像的颜色与这个特定问题的分类没有任何关系,并且增加了计算复杂性。我在下面附上了我的代码
ROWS,COLS = 669,1026
input_shape = (ROWS, COLS, 3)
base_model = applications.Xception(weights='imagenet',
include_top=False,
input_shape=(ROWS, COLS,3))
l = 0
for layer in base_model.layers:
layer.trainable = False
l += 1
c = 0
for layer in base_model.layers:
c += 1
if c > l-3:
layer.trainable = True
# for layer in base_model.layers:
# print(layer,layer.trainable)
# base_model.summary()
add_model = Sequential()
add_model.add(base_model)
add_model.add(GlobalAveragePooling2D())
# add_model.add(Dense(16, activation='tanh'))
# add_model.add(Dense(16, activation='tanh'))
add_model.add(Dense(8, activation='tanh'))
add_model.add(Dense(4, activation='tanh'))
add_model.add(Dense(1, activation='sigmoid'))
model = add_model
# model.compile(loss='binary_crossentropy',
# optimizer=optimizers.SGD(lr=1e-4,
# momentum=0.8),
# metrics=['accuracy'])
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.summary()
import numpy as np
import os
from random import shuffle
from tqdm import tqdm
from PIL import Image, ImageOps
import pickle
IMG_WIDTH = 669
IMG_HEIGHT = 1026
CLASS_1_TRAIN = '/home/spectrograms/train/c1'
CLASS_3_TRAIN = '/home/spectrograms/train/c3'
CLASS_1_TEST = '/home/spectrograms/test/c1'
CLASS_3_TEST = '/home/spectrograms/test/c3'
def label_img(img):
word_label = img[:5]
if img[1] == '1':
return [1,0]
elif img[1] == '3':
return [0,1]
def create_data(data,loc): #loads data into a list
for img in tqdm(os.listdir(loc)):
label = label_img(img)
path = os.path.join(loc,img)
img = Image.open(path)
img = ImageOps.grayscale(img)
# w,h = img.size
# img = img.resize((w//3,h//3))
data.append([np.array(img),np.array(label)])
return data
def make_X_and_Y(set): #split data into numpy arrays of inputs and outputs
set_X,set_Y = [],[]
n = len(set)
for i in range(n):
set_X.append(set[i][0])
set_Y.append(set[i][1])
return np.array(set_X),np.array(set_Y)
data = []
data = create_data(data,CLASS_1_TRAIN)
data = create_data(data,CLASS_1_TEST)
data = create_data(data,CLASS_3_TRAIN)
data = create_data(data,CLASS_3_TEST)
data = np.array(data)
np.random.shuffle(data)
X_data,Y_data = make_X_and_Y(data)
print('X-Y splittling completed\n')
print('X_Data.shape = ', X_data.shape)
print('Y_Data.shape = ', Y_data.shape)
from sklearn.model_selection import train_test_split
X_train, X_validation, Y_train, Y_validation = train_test_split(X_data, Y_data, test_size=0.3, random_state=42)
print('Test-train split completed\n')
X_train = X_train.reshape(X_train.shape[0], IMG_WIDTH, IMG_HEIGHT, 1)
X_validation = X_validation.reshape(X_validation.shape[0], IMG_WIDTH, IMG_HEIGHT, 1)
input_shape = (IMG_WIDTH, IMG_HEIGHT, 1)
X_train = X_train.astype('float32')
X_validation = X_validation.astype('float32')
X_train /= 255
X_validation /= 255
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
history = model.fit(X_train, Y_train,
batch_size=3,
epochs=100,
verbose = 1,
validation_data=(X_validation, Y_validation))
model.save_weights('/home/CNN/saved_model/Inception_new.h5')
如何更改我的代码,以便我可以在单层图像上训练 InceptionV3?如果不可能,是否有任何其他预训练模型可以完成此任务?
从头开始实施 Inceptionv3 很容易。因此,您可以遵循 https://gist.github.com/neggert/f8b86d001a367aa7dde1ab6b587246b5 或任何其他开源的 inceptionv3 模型,通道数从 3 到 1。但请注意,这些模型不会是预训练模型。因此,如果您有可用的 HPC 系统,可以尝试一下。
或
访问 https://github.com/keras-team/keras-applications/blob/master/keras_applications/inception_v3.py,他们在其中使用了预训练模型的权重,您可以在代码中将通道数从 3 更改为 1。我不确定这个,因为模型是在 3 通道图像上训练的,所以权重可能不是我们想要的。
我正在尝试使用迁移训练解决图像分类问题。我有一个 EEG 信号频谱图数据集。我想在此数据集上训练 InceptionV3 的最后几层。然而,InceptionV3 只采用三层图像,但我想在灰度图像上训练它,因为图像的颜色与这个特定问题的分类没有任何关系,并且增加了计算复杂性。我在下面附上了我的代码
ROWS,COLS = 669,1026
input_shape = (ROWS, COLS, 3)
base_model = applications.Xception(weights='imagenet',
include_top=False,
input_shape=(ROWS, COLS,3))
l = 0
for layer in base_model.layers:
layer.trainable = False
l += 1
c = 0
for layer in base_model.layers:
c += 1
if c > l-3:
layer.trainable = True
# for layer in base_model.layers:
# print(layer,layer.trainable)
# base_model.summary()
add_model = Sequential()
add_model.add(base_model)
add_model.add(GlobalAveragePooling2D())
# add_model.add(Dense(16, activation='tanh'))
# add_model.add(Dense(16, activation='tanh'))
add_model.add(Dense(8, activation='tanh'))
add_model.add(Dense(4, activation='tanh'))
add_model.add(Dense(1, activation='sigmoid'))
model = add_model
# model.compile(loss='binary_crossentropy',
# optimizer=optimizers.SGD(lr=1e-4,
# momentum=0.8),
# metrics=['accuracy'])
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.summary()
import numpy as np
import os
from random import shuffle
from tqdm import tqdm
from PIL import Image, ImageOps
import pickle
IMG_WIDTH = 669
IMG_HEIGHT = 1026
CLASS_1_TRAIN = '/home/spectrograms/train/c1'
CLASS_3_TRAIN = '/home/spectrograms/train/c3'
CLASS_1_TEST = '/home/spectrograms/test/c1'
CLASS_3_TEST = '/home/spectrograms/test/c3'
def label_img(img):
word_label = img[:5]
if img[1] == '1':
return [1,0]
elif img[1] == '3':
return [0,1]
def create_data(data,loc): #loads data into a list
for img in tqdm(os.listdir(loc)):
label = label_img(img)
path = os.path.join(loc,img)
img = Image.open(path)
img = ImageOps.grayscale(img)
# w,h = img.size
# img = img.resize((w//3,h//3))
data.append([np.array(img),np.array(label)])
return data
def make_X_and_Y(set): #split data into numpy arrays of inputs and outputs
set_X,set_Y = [],[]
n = len(set)
for i in range(n):
set_X.append(set[i][0])
set_Y.append(set[i][1])
return np.array(set_X),np.array(set_Y)
data = []
data = create_data(data,CLASS_1_TRAIN)
data = create_data(data,CLASS_1_TEST)
data = create_data(data,CLASS_3_TRAIN)
data = create_data(data,CLASS_3_TEST)
data = np.array(data)
np.random.shuffle(data)
X_data,Y_data = make_X_and_Y(data)
print('X-Y splittling completed\n')
print('X_Data.shape = ', X_data.shape)
print('Y_Data.shape = ', Y_data.shape)
from sklearn.model_selection import train_test_split
X_train, X_validation, Y_train, Y_validation = train_test_split(X_data, Y_data, test_size=0.3, random_state=42)
print('Test-train split completed\n')
X_train = X_train.reshape(X_train.shape[0], IMG_WIDTH, IMG_HEIGHT, 1)
X_validation = X_validation.reshape(X_validation.shape[0], IMG_WIDTH, IMG_HEIGHT, 1)
input_shape = (IMG_WIDTH, IMG_HEIGHT, 1)
X_train = X_train.astype('float32')
X_validation = X_validation.astype('float32')
X_train /= 255
X_validation /= 255
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
history = model.fit(X_train, Y_train,
batch_size=3,
epochs=100,
verbose = 1,
validation_data=(X_validation, Y_validation))
model.save_weights('/home/CNN/saved_model/Inception_new.h5')
如何更改我的代码,以便我可以在单层图像上训练 InceptionV3?如果不可能,是否有任何其他预训练模型可以完成此任务?
从头开始实施 Inceptionv3 很容易。因此,您可以遵循 https://gist.github.com/neggert/f8b86d001a367aa7dde1ab6b587246b5 或任何其他开源的 inceptionv3 模型,通道数从 3 到 1。但请注意,这些模型不会是预训练模型。因此,如果您有可用的 HPC 系统,可以尝试一下。
或
访问 https://github.com/keras-team/keras-applications/blob/master/keras_applications/inception_v3.py,他们在其中使用了预训练模型的权重,您可以在代码中将通道数从 3 更改为 1。我不确定这个,因为模型是在 3 通道图像上训练的,所以权重可能不是我们想要的。