Потери зависли с первой эпохи при использовании с float16 в 3D (Керас) - PullRequest
0 голосов
/ 22 марта 2020

У меня есть задача 3D-сегментации, которую я хотел бы решить с помощью CNN в керасе, используя патчи 64x64x64. Я знаю, что float16 более чем хорош для данных, которые я получаю при вводе. Это также более чем достаточно для вывода, это сегментация, это может быть даже uint8 (или bool). Если я работаю с float32, моя сеть работает отлично (я имею в виду ... столько, сколько вы можете ожидать, прежде чем оптимизировать ее). Я попытался переключиться на float16 для скорости и ... Потеря зависает от итерации 0, веса не обновляются и т.д. c ... Что я делаю не так? Я пробовал следующее: изменение функции потерь, изменение оптимизатора, изменение скорости обучения на много порядков. Я смог воспроизвести проблему с минимальным примером: сеть с 2 слоями, без понижающей дискретизации, которая должна научиться предсказывать сегментированные маски из самих масок. Прекрасно работает в float32, а не в float16. Я работаю в Colab с настройками по умолчанию, поэтому keras v2.2.5 и tenorflow 1.15.0

РЕДАКТИРОВАТЬ: больше обновлений Проблема, скорее всего, одна из числовых точность вычисления функции потерь при использовании float16 и патча 64x64x64. При использовании 32x32x32 это работает.

from keras import backend as K
from keras.engine import Input, Model
from keras.layers import Conv3D, Activation  

chosenDataType = 'float16' #swap between float16 and float32 to test
#set up a random, minimal 3D CNN
K.set_image_data_format("channels_last")
K.set_floatx(chosenDataType)
inputL = Input([64,64,64,1],dtype=chosenDataType)
l1 = Conv3D(32,[3,3,3],padding='same')(inputL)
l2 = Activation('relu') (l1)
l3 = Conv3D(32,[3,3,3],padding='same')(l2)
l4 = Activation('relu') (l3)
l5 = Conv3D(1,[1,1,1],padding='same')(l4)
model = Model(inputs=inputL,output=l5)
model.compile(optimizer='sgd',loss='mse')
#create some fake black images with white spots
import numpy as np
import random
X_train = np.zeros([30,64,64,64,1],dtype=chosenDataType)
for imIdx in range(30):
  centPoin = random.randrange(20,44)
  X_train[imIdx,centPoin-10:centPoin+10,centPoin-10:centPoin+10,centPoin-10:centPoin+10,0]=1
#ask the network to fit the images themselves.
Y_train = X_train.copy()
model.fit(X_train,Y_train,batch_size=30,epochs=100)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...