Я пытаюсь построить свою первую модель Keras, но она ничего не изучает. Я думаю, что эта проблема совершенно конкретна c для меня (то есть потому, что я делаю что-то не так, а не общий вопрос), поэтому дайте мне знать, если есть лучшее место для публикации.
Краткая версия: Я пытаюсь обучить сеть принимать в качестве входных данных список (представляющий изображение) и генерировать другой список / массив, который также можно отобразить в виде изображения. Тем не менее, потери не меняются во время обучения, и каждый вход дает одинаковый результат. См. Мой код ниже.
Контекст
- Я создал 2000 изображений «опухолей», таких как этот
- Для каждого изображения я смоделировал результаты ПЭТ-сканирования опухоли, которые представлены массивом, который может быть показан в виде изображения, подобного this . Каждая точка (x, y) показывает, сколько раз датчик x и датчик y ответили одновременно (что важно из-за физики). По этой причине каждое изображение фактически симметрично, поэтому для уменьшения объема данных я просто использую вложенный список, который содержит всю информацию (формат: [[a], [b, c], [d, e, f ], ...], где a - количество событий в сенсорной паре 0-0, b - сенсорная пара 1-0, c 1-1 и т.д. c.)
Цель
Я хочу обучить сеть, которая может go от результатов датчика до изображения опухоли. Поскольку это моя первая сеть, я хотел упростить для себя и обучить плотную сеть. Я знаю, что это не идеально, но на самом деле это был всего лишь тест, чтобы получить базовые результаты, но, похоже, я уже что-то делаю не так
Итак - кто-нибудь знает, что не так в моем коде ? Какой слой я должен использовать в качестве выходного слоя и с какой активацией? Какая была бы функция разумных потерь?
Код предварительной обработки (блокнот Jupyter и примеры изображений здесь ):
from PIL import Image
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
import pickle
def import_input(nr):
with open(Path('Sensor_half_matrixes_small/' + str(nr) + '.txt'), 'rb') as file:
data = pickle.load(file)
data = [item for sublist in data for item in sublist] #the file is in a format that I want to flatten
return data
def import_output(nr):
im = Image.open(Path('Math_tumor_images/' + str(nr) + '.png'))
a = np.array(im)
im.close()
a = a[:,:,0] #take only one color channel (they're all the same since it's grayscale)
a = np.full(a.shape, 255) - a #invert it so white=0, black=255. not sure this does anything, but it makes more sense to me
#downsample to 70*70. The original images are 420*420, but that seemed unnecessary
a = a[:, ::6] + a[:, 1::6] + a[:, 2::6] + a[:, 3::6] + a[:, 4::6] + a[:, 5::6]
a = a[::6, :] + a[1::6, :] + a[2::6, :] + a[3::6, :] + a[4::6, :] + a[5::6, :]
a = a.flatten() #flatten
a = a.tolist()
return(a)
input_list = []
output_list = []
for filenr in range(0,2000): #if you want to test it, I've only uploaded 21 images of each kind
input = import_input(filenr)
input_list.append(input)
output = import_output(filenr)
output_list.append(output)
input_tensor_train = np.array(input_list[:1400])
output_tensor_train = np.array(output_list[:1400])
input_tensor_test = np.array(input_list[1400:])
output_tensor_test = np.array(output_list[1400:])
Фактическая сеть Я предполагаю, что именно в этом проблема.
network = models.Sequential()
network.add(layers.Dense(2080, activation = 'relu', input_shape = (2080,)))
network.add(layers.Dense(2080,activation = 'relu'))
network.add(layers.Dense(4900, activation = 'sigmoid')) #I'm especially unsure about this layer. Is it even possible to 'upsample' from 2080 to 4900?
network.compile(optimizer = 'rmsprop', loss = 'mse') #Is there a better loss function? I guess I'm loosing some spatial information here...
history = network.fit(input_tensor_train, output_tensor_train, epochs=10, batch_size=32, validation_split=0.2)
Результат Во время подбора потери остаются теми же с небольшими вариациями, как для проверки, так и для проверки. для нормальных тренировочных данных. Когда я пытаюсь предсказать, используя network.predict(input_tensor_test)
, я получаю несколько очень похожих массивов для каждого входа, и когда я пытаюсь отобразить их в виде изображений, они неразличимы - это на самом деле выглядит как правильный ответ ( это смутно кружок- esque ), но оно не должно быть одинаковым для каждого входа.