Страницы

Поиск по вопросам

Показаны сообщения с ярлыком keras. Показать все сообщения
Показаны сообщения с ярлыком keras. Показать все сообщения

понедельник, 30 марта 2020 г.

Сохранение лучшей модели

#python #нейронные_сети #машинное_обучение #keras


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

Можно ли организовать обучение сети таким образом, чтобы после каждой эпохи сравнивать
получившуюся сеть с лучшей? Чтобы после того, как пройдет заданное количество эпох,
была получена лучшая сеть за все время обучения, а не сеть после обучения на заданное
количество эпох.
    


Ответы

Ответ 1



Вы можете воспользоваться callbacks для сохранения лучшей модели и для ранней остановки (чтобы избежать бесполезных вычислений и ускорить время обучения модели): from keras.callbacks import EarlyStopping, ModelCheckpoint early_stop = EarlyStopping(monitor='val_acc', min_delta=0.0001, patience=5, verbose=1, mode='auto') chkpt = ModelCheckpoint(model_filename, monitor='val_loss', verbose=1, save_best_only=True, mode='auto') callbacks = [early_stop, chkpt] hist = model.fit(x_train, y_train, batch_size=Batch_size, epochs=Epochs, validation_data=(x_val, y_val), callbacks=callbacks)

пятница, 28 февраля 2020 г.

Какие могут быть пути улучшения обобщающей способности ИНС на базе Keras?

#python #нейронные_сети #машинное_обучение #keras


Несколько дней назад я создавал тему с похожим вопросом: Проблема с обучением сети
в Keras: нет обобщающей способности сети, и там получил резонное замечание и совет.
Решив попробовать поработать с данными, в которых информация не утрачена (нежели в
прошлом топике), я собрал подобную ИНС, предварительно нормализовав данные (использование
StandardScaler оказалось лучше MinMax).

Дано:
База из 71 осциллограммы с 3002 отсчетами. Диапазон данных: от 0 до 10Е6. Данные
векторы разбиты на обучающую выборку и тестовую (36 и 35).  

Задача:
входным векторам присваивать значения на выходе в виде определенного числа (от 30
до 100). 

Ограничения:
нет возможности получить огромный датасет (из тысяч векторов) и возможный максимум
- сотня-полторы векторов.

Текущая конфигурация сети довольно неплохо обучается (в сравнении с предыдущей),
однако проблема с обобщением результатов все также существует. Хоть результат и лучше
он все еще не устраивает меня. Меняя конфигурации многослойного персептрона (число
нейронов в слое, число слоев) мне не удавалось сильно изменять выходной результат (разве
что, кроме времени обучения, что логично). Возможно я не подобрался к самой оптимальной
структуре ИНС, но пока есть только это. Кстати да, функцию обучения выбирал методом
научного тыка. Перепробовал разные методы и данный показал себя лучше всего.

Итак, отсюда у меня вопросы:
Какие возможные пути изменения ИНС для улучшения результата? К сожалению я все еще
новичок в этой области и знаком только с персептронами. Быть может вы сможете посоветовать
какие-то другие типы сетей? Если после нормализации у меня диапазон значений вектора
от -2 до 6, то как это влияет? На сколько мне известно, то на вход сети следует подавать
данные в диапазоне [0 1] или [-1 1].

Код сети:

#загружаем файл с образами
TRAIN_FILE="TRAIN30_100km.csv"
TEST_FILE="TEST30_100km.csv"

# размер вектора
img_rows, img_cols = 1, 3002

# Загружаем данные для обучения
train_dataset = np.loadtxt(TRAIN_FILE, skiprows=0, dtype='int', 
delimiter=",")
test_dataset = np.loadtxt(TEST_FILE, skiprows=0, dtype='int', delimiter=",")

# Выделяем данные для обучения
X_train = train_dataset[:, 1:]
X_test = test_dataset[:, 1:]

# нормализуем данные
scaler = StandardScaler()
x_train=scaler.fit_transform(X_train)
x_test=scaler.fit_transform(X_test)

# Выделяем правильные ответы
y_train = train_dataset[:,0]
y_test = test_dataset[:,0] 

# рисуем график нормализованного вектора и оригинального
y10 = x_train[6, :]
y11=X_train[6, :]
plt.figure(figsize=(8, 8))
plt.plot(y10)
plt.show()
plt.figure(figsize=(8, 8))
plt.plot(y11)
plt.show()

# Выделяем правильные ответы
y_train = train_dataset[:,0]
y_test = test_dataset[:,0]

model = Sequential()

model.add(Dense(10, input_dim=3002, 
activation="relu",kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(15, activation='relu', 
kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(5, activation='relu', 
kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(5, activation='relu'))
model.add(Dense(1))
model.compile( optimizer='Adagrad', loss="mse", metrics=['mae'])

print(model.summary())
model.fit(x_train, y_train, epochs=30, batch_size=1, 
verbose=2,validation_data=(x_test, y_test))



  Epoch 30/30
   - 0s - loss: 0.9548 - mean_absolute_error: 0.1053 - val_loss: 102.0822 - val_mean_absolute_error:
7.7214


mse, mae = model.evaluate(x_test, y_test, verbose=0)
predictions=model.predict(x_test)
print(predictions)
# ответы (правильные 31 33 35 37)
[20.31354 ]
[18.931906]
[21.085878]
[20.537167]


Ссылка на датасет.
    


Ответы

Ответ 1



Немного подумав, решил упростить НС по-максимуму и получил лучшие показатели. Архитектура: model = Sequential() model.add(Dense(128, input_dim=3002, activation="relu", kernel_regularizer=l2(0.01))) model.add(BatchNormalization()) model.add(Dense(1)) model.compile( optimizer='Adagrad', loss="mse", metrics=['mae', 'mse']) hist = model.fit(x_train, y_train, epochs=300, batch_size=3, verbose=2,validation_data=(x_test, y_test), callbacks=callbacks) вывод: Epoch 00147: val_mean_squared_error did not improve from 13.76798 Epoch 148/300 - 0s - loss: 183.8615 - mean_absolute_error: 10.9775 - mean_squared_error: 180.3115 - val_loss: 23.7155 - val_mean_absolute_error: 3.2763 - val_mean _squared_error: 20.1659 Epoch 00148: val_mean_squared_error did not improve from 13.76798 Epoch 00148: early stopping оценка: In [206]: model = load_model(model_fn) In [207]: model.evaluate(x_test, y_test, verbose=1) 18/18 [==============================] - 2s 135ms/step Out[207]: [17.30735206604004, 3.1715924739837646, 13.767986297607422] сравнение тестового набора с предсказанными значениями: In [208]: from sklearn.metrics import mean_absolute_error, mean_squared_error In [209]: df = pd.DataFrame({'y_test':y_test.ravel(), 'y_pred':model.predict(x_test).ravel()}) In [210]: mean_squared_error(df['y_test'], df['y_pred']) Out[210]: 13.76798614917061 In [211]: mean_absolute_error(df['y_test'], df['y_pred']) Out[211]: 3.171592500474718 In [212]: df['abs_err'] = np.abs(df['y_test'] - df['y_pred']) In [213]: df Out[213]: y_test y_pred abs_err 0 39.0 41.414223 2.414223 1 41.0 38.207268 2.792732 2 43.0 49.000561 6.000561 3 73.0 73.476303 0.476303 4 33.0 32.048149 0.951851 5 78.0 76.682877 1.317123 6 53.0 57.643074 4.643074 7 54.0 58.276382 4.276382 8 67.0 63.092651 3.907349 9 49.0 53.009842 4.009842 10 89.0 87.252930 1.747070 11 65.0 62.399197 2.600803 12 63.0 68.281502 5.281502 13 58.0 55.078934 2.921066 14 48.0 43.649544 4.350456 15 80.0 72.487808 7.512192 16 60.0 60.331455 0.331455 17 47.0 45.445320 1.554680 In [217]: df[['y_test','y_pred']].plot() Out[217]:

Ответ 2



Немного поигрался с вашими данными - лучшее что у меня получилось: mae: 3.8784 mse: 22.78249 вот весь код: import pandas as pd import numpy as np from pathlib import Path from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from keras import Sequential from keras.layers import * from keras.regularizers import l2, l1 from keras.callbacks import EarlyStopping, ModelCheckpoint from keras.models import save_model, load_model def get_data(path, test_size=0.25): data = pd.concat([pd.read_csv(f, header=None) for f in Path(path).glob('*.csv')], ignore_index=True).values scaler = StandardScaler() x, y = scaler.fit_transform(data[:, 1:]), data[:, [0]] return train_test_split(x, y, test_size=test_size) path = r'/path/to/directory_with_data' x_train, x_test, y_train, y_test = \ get_data(path, test_size=0.25) model_fn = str(Path(path) / 'model.h5') early_stop = EarlyStopping(monitor='val_mean_squared_error', min_delta=0.0001, patience=60, verbose=1, mode='auto') chkpt = ModelCheckpoint(model_fn, monitor='val_mean_squared_error', verbose=1, save_best_only=True, mode='auto') callbacks = [early_stop, chkpt] model = Sequential() model.add(Dense(45, input_dim=3002, activation="relu", kernel_regularizer=l2(0.01))) model.add(BatchNormalization()) model.add(Dropout(0.04)) model.add(Dense(20, activation='relu', kernel_regularizer=l2(0.01))) model.add(Dropout(0.01)) model.add(Dense(6, activation='relu', kernel_regularizer=l2(0.01))) model.add(Dense(5, activation='relu')) model.add(Dense(1)) model.compile( optimizer='adam', loss="mse", metrics=['mae', 'mse']) hist = model.fit(x_train, y_train, epochs=300, batch_size=3, verbose=2,validation_data=(x_test, y_test), callbacks=callbacks) Сохраненная модель ...

пятница, 14 февраля 2020 г.

ValueError: Error when checking input: expected input_120 to have 3 dimensions, but got array with shape (96, 7)

#python #python_3x #нейронные_сети #машинное_обучение #keras


У меня есть такой код:

a=[[1,23,345,235,235,644,757],
[2,455,325,235578,23524,6413,757567],
[3,123,125,2375,23554,64123,75778],
[...],
[35,244,245,231235,2158935,6567944,7567557]]

b=[[1],[-1],[0],[...],[1]]

c=np.array(a)
d=np.array(b)
print(c.shape)
print(d.shape)

inputs = Input(shape=(96,7))
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(c, d)


Выводит:

(96, 7)
(96, 1)
ValueError: Error when checking input: expected input_120 to have 3 dimensions, but
got array with shape (96, 7)


Никак не могу понять в чем же тут проблема. Помогите пожалуйста.
    


Ответы

Ответ 1



у вас тут похоже две проблемы: число строк (образцов) в размерности модели не учитывается. Т.е. вместо inputs = Input(shape=(96,7)) используйте: inputs = Input(shape=(7,)) На последнем слое вы использовали 10 выходных нейронов (иными словами вы хотите посчитать вероятности принадлежности к 10-ти классам), а на вход (в качестве y/target) вы подаете тензор/матрицу с одним столбцом (модель же ожидает 10 столбцов). Для того чтобы исправить 2-ю проблему можно категоризировать (One-Hot-Encoding) d, получив в итоге "One Hot Encoded" матрицу с 10-ю столбцами. Пример: In [46]: from keras.utils import to_categorical In [47]: Y = to_categorical(d, num_classes=10) In [48]: Y Out[48]: array([[0., 1., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.], [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32) Весь исправленный код: from keras import Model, Sequential from keras.layers import * from keras.utils import to_categorical a=[[1,23,345,235,235,644,757], [2,455,325,235578,23524,6413,757567], [3,123,125,2375,23554,64123,75778], [35,244,245,231235,2158935,6567944,7567557]] b=[[1],[-1],[0],[1]] X = np.array(a) Y = to_categorical(np.array(b), num_classes=10) model = Sequential() model.add(Dense(64, activation='relu', input_dim=7)) model.add(Dense(64, activation='relu')) model.add(Dense(10, activation='softmax')) model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) print(model.summary()) model.fit(X, Y)

среда, 22 января 2020 г.

Как подать массив данных Y из обучающей выборки на вход классифирующей модели?

#python #нейронные_сети #машинное_обучение #keras #tensorflow


Есть модель, нужно подать данные (массив входных и выходных значений) так, чтобы
модель классифицировала данные, и указать нужную функцию активации на последнем слое
и функцию потерь. То же самое сделать для Унитарно кодированного вектора на выходном
массиве данных. 

([0,0,1] первое значение, [0,1,0] второе значение, [1,0,0] третье значение) 

Во всех статьях и книгах данные загружаются уже готовые из репозиториев, но если
создавать собственные данные то возникает проблема.

    import tensorflow as tf
import numpy as np
from keras.models import Sequential
from keras.layers import Input, Dense, Activation
from sklearn import preprocessing
model=Sequential()
X = np.array([[40, 80, 30, 60], [100, 40, 20, 80], [90, 190, 10, 15]])
Y = np.array([[0], [1], [2]])

model = Sequential()
model.add(Dense(16, input_shape=(X.shape[1],)))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(3))
model.compile(loss='mean_squared_error', optimizer='Adamax', metrics=['mae'])

model.fit(X,Y,batch_size=3,epochs=1000,
          verbose=1)
a=np.array([40, 80, 30, 60]);
   reshy =a.reshape((1,- 1))
print("test")
print(reshy)
prediction = model.predict(reshy)
print('prediction')
print(prediction)

    


Ответы

Ответ 1



То что вы пытаетесь сделать называется Multilabel Classification. В этом случае массив Y необходимо преобразовать к One-Hot-Encoded виду: from keras.utils import to_categorical Y = to_categorical(Y) чтобы получилось: In [76]: Y Out[76]: array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]], dtype=float32) Кроме этого надо будет изменить архитектуру НС: model = Sequential() model.add(Dense(4, input_shape=(X.shape[1],), activation='relu')) model.add(BatchNormalization()) model.add(Dense(20, activation='relu')) model.add(Dense(3, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='Adamax', metrics=['acc']) NOTE: обратите внимание на loss-function: loss='categorical_crossentropy' и функцию активации на последнем слое: activation='softmax'. Вывод: ... Epoch 47/50 3/3 [==============================] - 0s 0us/step - loss: 0.3294 - acc: 1.0000 Epoch 48/50 3/3 [==============================] - 0s 0us/step - loss: 0.3226 - acc: 1.0000 Epoch 49/50 3/3 [==============================] - 0s 2ms/step - loss: 0.3158 - acc: 1.0000 Epoch 50/50 3/3 [==============================] - 0s 0us/step - loss: 0.3091 - acc: 1.0000 test [[40 80 30 60]] prediction [[0.5021875 0.297052 0.20076045]] Весь код: import tensorflow as tf import numpy as np from keras.utils import to_categorical from keras.models import Sequential from keras.layers import Input, Dense, Activation, BatchNormalization from sklearn import preprocessing model=Sequential() X = np.array([[40, 80, 30, 60], [100, 40, 20, 80], [90, 190, 10, 15]]) Y = np.array([[0], [1], [2]]) Y = to_categorical(Y) model = Sequential() model.add(Dense(4, input_shape=(X.shape[1],), activation='relu')) model.add(BatchNormalization()) model.add(Dense(20, activation='relu')) model.add(Dense(3, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='Adamax', metrics=['acc']) model.fit(X,Y,batch_size=3,epochs=100, verbose=1) a=np.array([40, 80, 30, 60]); reshy =a.reshape((1,- 1)) print("test") print(reshy) prediction = model.predict(reshy) print('prediction') print(prediction)

четверг, 2 января 2020 г.

Обучение нейронной сети теореме Пифагора

#python #нейронные_сети #машинное_обучение #keras #обучение_с_подкреплением


Хочу обучить НС теореме Пифагора. Всё вроде правильно сделал, нормализовал данные,
модель правильная, а вот в чём ошибка не понятно..

import numpy as np

from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils import np_utils

np.random.seed()

NB_EPOCH = 500
VERBOSE = 1

X_in = [[ 0 , 44 ], [ 0 , 18 ], [ 38 , 0 ], [ 48 , 14 ], [ 0 , 36 ], [ 14 , 0 ],
[ 34 , 0 ], [ 0 , 0 ], [ 0 , 38 ], [ 32 , 0 ], [ 28 , 0 ], [ 36 , 0 ], [ 20 , 48 ],
[ 0 , 6 ], [ 0 , 20 ], [ 0 , 42 ], [ 0 , 8 ], [ 24 , 32 ], [ 4 , 0 ], [ 6 , 8 ], [
24 , 10 ], [ 0 , 22 ], [ 16 , 12 ], [ 30 , 40 ], [ 0 , 32 ], [ 0 , 32 ], [ 16 , 0 ],
[ 48 , 20 ], [ 0 , 8 ], [ 32 , 0 ], [ 0 , 46 ], [ 0 , 22 ], [ 0 , 8 ], [ 10 , 24 ],
[ 0 , 36 ], [ 14 , 0 ], [ 0 , 22 ], [ 42 , 0 ], [ 16 , 12 ], [ 40 , 30 ], [ 44 , 0
], [ 40 , 0 ], [ 34 , 0 ], [ 0 , 32 ], [ 40 , 30 ], [ 32 , 0 ], [ 0 , 30 ], [ 24 ,
18 ], [ 0 , 26 ], [ 22 , 0 ], [ 0 , 4 ], [ 16 , 0 ], [ 10 , 0 ], [ 0 , 32 ], [ 0 ,
42 ], [ 2 , 0 ], [ 0 , 38 ], [ 32 , 24 ], [ 48 , 0 ], [ 20 , 0 ], [ 0 , 18 ], [ 0 ,
38 ], [ 14 , 48 ], [ 40 , 42 ], [ 16 , 12 ], [ 26 , 0 ], [ 0 , 20 ], [ 40 , 30 ], [
16 , 30 ], [ 36 , 48 ], [ 36 , 0 ], [ 18 , 24 ], [ 34 , 0 ], [ 16 , 0 ], [ 0 , 24 ],
[ 0 , 24 ], [ 0 , 18 ], [ 38 , 0 ], [ 28 , 0 ], [ 0 , 34 ], [ 0 , 36 ], [ 24 , 32 ],
[ 16 , 30 ], [ 40 , 30 ], [ 24 , 0 ], [ 0 , 14 ], [ 8 , 6 ], [ 12 , 0 ], [ 16 , 0 ],
[ 16 , 30 ], [ 48 , 14 ], [ 0 , 30 ], [ 38 , 0 ], [ 38 , 0 ], [ 0 , 8 ], [ 36 , 48
], [ 0 , 32 ], [ 10 , 24 ], [ 46 , 0 ], [ 24 , 10 ], [ 30 , 0 ], [ 0 , 48 ], [ 40 ,
0 ], [ 42 , 0 ], [ 32 , 24 ], [ 32 , 0 ], [ 12 , 16 ], [ 0 , 4 ], [ 0 , 28 ], [ 32
, 0 ], [ 40 , 42 ], [ 46 , 0 ], [ 0 , 24 ], [ 30 , 16 ], [ 36 , 48 ], [ 40 , 0 ], [
24 , 0 ], [ 0 , 22 ], [ 40 , 42 ], [ 10 , 24 ], [ 0 , 16 ], [ 14 , 48 ], [ 22 , 0 ],
[ 0 , 22 ], [ 30 , 0 ], [ 0 , 2 ], [ 48 , 20 ], [ 6 , 0 ], [ 6 , 0 ], [ 28 , 0 ], [
20 , 0 ], [ 0 , 40 ], [ 42 , 0 ], [ 48 , 36 ], [ 14 , 0 ], [ 10 , 24 ], [ 0 , 30 ],
[ 48 , 20 ], [ 40 , 30 ], [ 0 , 0 ], [ 42 , 40 ], [ 0 , 48 ], [ 32 , 24 ]]
X_answer = [[44] ,[18] ,[38] ,[50] ,[36] ,[14] ,[34] ,[0] ,[38] ,[32] ,[28] ,[36]
,[52] ,[6] ,[20] ,[42] ,[8] ,[40] ,[4] ,[10] ,[26] ,[22] ,[20] ,[50] ,[32] ,[32] ,[16]
,[52] ,[8] ,[32] ,[46] ,[22] ,[8] ,[26] ,[36] ,[14] ,[22] ,[42] ,[20] ,[50] ,[44] ,[40]
,[34] ,[32] ,[50] ,[32] ,[30] ,[30] ,[26] ,[22] ,[4] ,[16] ,[10] ,[32] ,[42] ,[2] ,[38]
,[40] ,[48] ,[20] ,[18] ,[38] ,[50] ,[58] ,[20] ,[26] ,[20] ,[50] ,[34] ,[60] ,[36]
,[30] ,[34] ,[16] ,[24] ,[24] ,[18] ,[38] ,[28] ,[34] ,[36] ,[40] ,[34] ,[50] ,[24]
,[14] ,[10] ,[12] ,[16] ,[34] ,[50] ,[30] ,[38] ,[38] ,[8] ,[60] ,[32] ,[26] ,[46]
,[26] ,[30] ,[48] ,[40] ,[42] ,[40] ,[32] ,[20] ,[4] ,[28] ,[32] ,[58] ,[46] ,[24]
,[34] ,[60] ,[40] ,[24] ,[22] ,[58] ,[26] ,[16] ,[50] ,[22] ,[22] ,[30] ,[2] ,[52]
,[6] ,[6] ,[28] ,[20] ,[40] ,[42] ,[60] ,[14] ,[26] ,[30] ,[52] ,[50] ,[0] ,[58] ,[48]
,[40]]
X_in = np.asarray(X_in, dtype=np.float32)
X_answer = np.asarray(X_answer, dtype=np.float32)

X_in /= np.amax(X_in)
X_answer /= np.amax(X_answer)

model = Sequential()
model.add(Dense(10, input_dim = 2, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='softmax'))

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

history = model.fit(X_in, X_answer, epochs=NB_EPOCH, verbose=VERBOSE)


Что до 100 эпох, что до 500 один и тот же результат:

Epoch 1/100
143/143 [==============================] - 0s 2ms/step - loss: 0.2966 - acc: 0.0280
Epoch 2/100
143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280
Epoch 3/100
143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280
Epoch 4/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 5/100
143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280
Epoch 6/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 7/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 8/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 9/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 10/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 11/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 12/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 13/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 14/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 15/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 16/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 17/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 18/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 19/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 20/100
143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280
Epoch 21/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 22/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 23/100
143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280
Epoch 24/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 25/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 26/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 27/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 28/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 29/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 30/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 31/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 32/100
143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280
Epoch 33/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 34/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 35/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 36/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 37/100
143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280
Epoch 38/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 39/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 40/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 41/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 42/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 43/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 44/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 45/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 46/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 47/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 48/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 49/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 50/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 51/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 52/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 53/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 54/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 55/100
143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280
Epoch 56/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 57/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 58/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 59/100
143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280
Epoch 60/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 61/100
143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280
Epoch 62/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 63/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 64/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 65/100
143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280
Epoch 66/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 67/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 68/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 69/100
143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280
Epoch 70/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 71/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 72/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 73/100
143/143 [==============================] - 0s 39us/step - loss: 0.2966 - acc: 0.0280
Epoch 74/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 75/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 76/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 77/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 78/100
143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280
Epoch 79/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 80/100
143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280
Epoch 81/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 82/100
143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280
Epoch 83/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 84/100
143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280
Epoch 85/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 86/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 87/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 88/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 89/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 90/100
143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280
Epoch 91/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 92/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 93/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280
Epoch 94/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 95/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 96/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 97/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 98/100
143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280
Epoch 99/100
143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280
Epoch 100/100
143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280

    


Ответы

Ответ 1



Как уже сказал @L.Murashov функция активации softmax применяется в задачах мультиклассовой классификации - она помогает посчитать вероятности принадлежности образца каждому из классов. Есть еще несколько моментов, на которые стоит обратить внимание: В обучающей выборке слишком много (около половины) нулевых значений - это вырожденный случай для теоремы Пифагора, когда одна из сторон треугольника имеет нулевую длину. Для того, чтобы лучше обучить модель можно выборку взять побольше - в вашем случае не проблема сгенерировать столько данных сколько нужно. Для данной (простой) задачи хватит одного скрытого слоя В качестве функции активации выходного слоя можно использовать linear В качестве функции потери и метрики можно выбрать mean_squared_error Пример: import numpy as np from keras.models import Sequential from keras.layers.core import Dense, Activation N = 5000 np.random.seed(1234) X = np.random.randint(0, 50, size=(N,2)) y = np.linalg.norm(X, axis=1) NB_EPOCHS = 100 VERBOSE = 1 model = Sequential() model.add(Dense(20, input_dim = 2, activation='relu')) model.add(Dense(1, activation='linear')) model.compile(loss='mse', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=NB_EPOCHS, verbose=VERBOSE) Обучение: ... 5000/5000 [==============================] - 0s 22us/step - loss: 0.0057 - mean_squared_error: 0.0057 Epoch 98/100 5000/5000 [==============================] - 0s 22us/step - loss: 0.0048 - mean_squared_error: 0.0048 Epoch 99/100 5000/5000 [==============================] - 0s 22us/step - loss: 0.0045 - mean_squared_error: 0.0045 Epoch 100/100 5000/5000 [==============================] - 0s 22us/step - loss: 0.0043 - mean_squared_error: 0.0043 Out[70]: Предсказание: In [71]: model.predict(np.array([[3,4], [10,10], [5,6]])) Out[71]: array([[ 5.018393], [14.130004], [ 7.841759]], dtype=float32)

Ответ 2



У вас неправильная функция активации на последнем слое. Softmax ограничен [0..1] model.add(Dense(1, activation='softmax')) заменить на # После слоя не применяется функция активации model.add(Dense(1)) Еще accuracy здесь бесполезна т.к. задача регрессии. metrics=['accuracy']

среда, 25 декабря 2019 г.

Нейросеть для векторов размером 360(радар). Подскажите базовую архитектуру для доработок

#нейронные_сети #keras


Всем хелоу.

Прилетела сферическая задача научить "робота" с радаром определять где же он. Если
опустить все подробности то в сухом остатке мы имеем следующее:


есть набор векторов размером в 360 и значениями от 0. до 0.4500 (примерно, погрешность
радара плавает).
имеющее достаточно уникальный в оси Х рельеф помещение разбито на 10 условных секторов
и в каждом из них были сняты показания радара по 10000 раз (если надо больше то легко)
на каждый вектор снятых данных(это массив размером 360 где значением является расстояние
до приграды) "варится" еще по по 3, где этот вектор поворачивается по 90 градусов(т.е.
90,180,270 возможна реализация других трансформаций данных, например, масштаб или сдвиг)
т.к. помещение было разбито на 10 секторов то задача определить к какому из 10 секторов
относится "слепок" с радара (т.е. вектор размером 360).


Что было сделано:


ну да, разбил помещение на 10 "образных" секторов
и конечно, сделал замеры по 10к раз с каждого из них
козалось бы, но написал "подготовку данных" где мы крутим каждый снятый вектор на
90 градусов
и что не мало важно, смог за пару дней "раскурить" keras и извоять там  простую сеть
LSTM в 4 слоя




т.к. никто не разбирается в "нейросетевой" архитектуре был взят один из примеров
кластирезации из гугл-источника

model = Sequential()
model.add(LSTM(32, return_sequences=True,
           input_shape=(1, 360)))
model.add(LSTM(32, return_sequences=True))
model.add(LSTM(32))
model.add(Dense(10, activation='softmax'))


Сетке были скормлены более 200000 замеренных с 10 секторов векторов + их обработка
с поворотом по 90 градусов, в качестве "учителя" были даны варианты правильного определения(
[0 1 0 0 0 0 0 0 0 0] например для определения 2го сектора и [0 0 0 0 0 0 0 0 0 1]
для определения последнего, остальные включительно)

После 10-20 эпох резултат впечатлил, 99% val_acc и любой пердикшен выдает как буддто
знает к какому сектору относится вектор, и на 90, 180,270 тоже и на +/- 2 градуса но...

стоит повернуть практически любой вектор через np.roll более чем на 3-4 грудса от
векторов на которых обучалась сеть то сразу получаем ошибку определения класса.

Вопрос: Подскажите примерную, базовую архитектуру сети которая бы принимала фигуру(n,
1, 360) и при обучении "крепчала" не от того что ей показывают тысячи вариантов векторов
повернутых по 1 градусу с каждого сектора, а была бы способна выявлять признаки "не
особо" зависящие от поворота
    


Ответы

Ответ 1



Я бы первым делом исключил вращение, насколько получится, чтобы не кормить НС лишними данными. Нужна какая-то функция, которая для каждой картины радара будет более-менее однозначно определять нулевую точку. В данной задаче, как для меня выглядит ее специфика, это более реально, чем, например, компенсация вращения символа в капче. Немного дополняю ответ. Компенсация вращения это подготовка входных данных (не обучающих). Этим исключается необходимость для нейросети научиться вращать входной вектор самостоятельно. Даже если функция, определяющая точку отсчета входного вектора дает сбои, то это проявляется лишь в нескольких сдвинутых вариантах входного вектора при одних и тех же координатах робота. Это все равно намного экономней 360 вариантов на каждый по сути один и тот же входной вектор за вычетом сдвига. Похожий подход следует применить и для выходных данных. А именно, выход - это два блока сигналов. Например, вы хотите чтобы определялись коородинаты робота по x и y. Все пространство делится на сетку, например, 1000x1000. У НС будет 2000 выходов. Таким образом исключается необходимость для нейросети учиться формировать двоичные числа.

вторник, 24 декабря 2019 г.

Препроцессинг текста для обучения модели классификации в Keras

#python #нейронные_сети #машинное_обучение #numpy #keras


Я написал скрипт нейронной сети, а точнее часть с подготовкой данных на вход. Но
не уверен, правильно ли всё сделал для того, чтобы модель смогла корректно обучаться.
Очень нужна оценка знающих людей.

Код:

import sklearn
import numpy as np
from collections import Counter
from keras.models import model_from_json
from keras.preprocessing import sequence
from sklearn.model_selection import train_test_split as tts


labels_lexicon = ['_label_0', '_label_1', '_label_2'] # список категорий

def get_data_from_the_file():
  labels, descriptions, lexicon, lexicon_base = [], [], [], []
  for i,  line in enumerate(open('testtext.txt', 'r', encoding='utf8', errors='ignore')):
    content = line.split()
    labels.append([content[0]])
    descriptions.append(content[1:])
    lexicon_base += content[1:]

  count_lexicon = Counter(lexicon_base).most_common(5000)
  for count_item in count_lexicon:
   lexicon.append(count_item[0])

  return labels, descriptions, lexicon

labels, descriptions, lexicon = get_data_from_the_file()

def get_descriptions_to_index(lexicon):
    cache = {}
    word2index = {}
    for i,word in enumerate(lexicon):
        if cache.get(word) == None:
            cache[word] = i
            word2index[word] = i
    return word2index
word2index = get_descriptions_to_index(lexicon)


def get_labels_to_index(labels_lexicon):
    cache = {}
    labels2index = {}
    for i,word in enumerate(labels_lexicon):
        if cache.get(word) == None:
            cache[word] = i
            labels2index[word] = i
    return labels2index
labels2index = get_labels_to_index(labels_lexicon)

list_of_tokenize_descriptions = []
list_of_tokenize_labels = []


for descriptions_arrays in descriptions:
    prepare_list_of_tokenize_descriptions = []
    for descriptions_piece in descriptions_arrays:
        if word2index.get(descriptions_piece) != None:
            prepare_list_of_tokenize_descriptions.append(word2index[descriptions_piece])
    list_of_tokenize_descriptions.append(prepare_list_of_tokenize_descriptions)


for labels_arrays in labels:
    prepare_list_of_tokenize_labels = []
    for labels_piece in labels_arrays:
        if labels2index.get(labels_piece) != None:
            prepare_list_of_tokenize_labels.append(labels2index[labels_piece])
    list_of_tokenize_labels.append(prepare_list_of_tokenize_labels)

x_matrix_list = []
y_matrix_list = []

for i in range(len(list_of_tokenize_descriptions)):
  matrix_i = np.zeros((len(lexicon)),dtype=int)
  line =  list_of_tokenize_descriptions[i]
  for index in line:
    matrix_i[index] = 1
  x_matrix_list.append(matrix_i)


for i in range(len(list_of_tokenize_labels)):
  matrix_i = np.zeros((len(labels_lexicon)),dtype=int)
  line =  list_of_tokenize_labels[i]
  for index in line:
    matrix_i[index] = 1
  y_matrix_list.append(matrix_i)


x_train, x_test, y_train, y_test = tts(np.array(x_matrix_list), np.array(y_matrix_list),
 test_size=0.3)


Здесь ссылкуа на dataset. 
    


Ответы

Ответ 1



Я бы в данном случае воспользовался методом keras.preprocessing.text.Tokenizer: from pathlib import Path import pandas as pd from keras.models import Sequential from keras.layers import Embedding, LSTM, Dense, Dropout, Activation from keras.preprocessing.text import Tokenizer, text_to_word_sequence from keras.preprocessing.sequence import pad_sequences from keras import optimizers from keras.callbacks import ModelCheckpoint from keras.models import load_model from sklearn.model_selection import train_test_split def get_data(filename, num_words=5000, frac=1.0): data = (pd.read_csv(filename, header=None, names=['text'], sep='~') .sample(frac=frac)) data[['label','text']] = data.pop('text').str.split(n=1, expand=True) data = data.dropna() data = data.loc[data['label'].str.contains(r'^_label')] # build vocabulary tok = Tokenizer(num_words=num_words) tok.fit_on_texts(data['text']) # convert texts to sequences X = tok.texts_to_sequences(data['text']) lb = LabelBinarizer() Y = pd.DataFrame(lb.fit_transform(data['label']), columns=lb.classes_, index=data.index) return (pad_sequences(X, maxlen=num_words), Y, tok) path = Path(r'D:\temp\.data') filename = path / 'testtext.txt' num_words = 1000 X, Y, tok = get_data(filename, num_words=num_words) # split data set to train / dev X_train, X_dev, Y_train, Y_dev = \ train_test_split(X, Y, test_size=0.2, random_state=123, stratify=Y) print('X_train.shape:\t{}\t\tY_train.shape:\t{}'.format(X_train.shape, Y_train.shape)) print('X_dev.shape:\t{}\t\tY_dev.shape:\t{}'.format(X_dev.shape, Y_dev.shape)) вывод: X_train.shape: (26850, 1000) Y_train.shape: (26850, 3) X_dev.shape: (6713, 1000) Y_dev.shape: (6713, 3) Что у нас получилось: In [4]: X Out[4]: array([[ 0, 0, 0, ..., 250, 154, 16], [ 0, 0, 0, ..., 112, 121, 84], [ 0, 0, 0, ..., 72, 49, 44], ..., [ 0, 0, 0, ..., 5, 109, 99], [ 0, 0, 0, ..., 158, 513, 78], [ 0, 0, 0, ..., 0, 0, 138]]) In [5]: X.shape Out[5]: (33563, 1000) In [6]: Y Out[6]: _label_0 _label_1 _label_2 30455 1 0 0 19423 1 0 0 29907 0 1 0 12779 0 1 0 28342 0 0 1 27583 0 0 1 28096 0 1 0 21411 1 0 0 23425 1 0 0 33227 1 0 0 ... ... ... ... 28788 1 0 0 17329 0 1 0 5339 0 1 0 9461 0 0 1 31315 0 0 1 23199 1 0 0 6752 0 1 0 164 1 0 0 24283 0 0 1 25055 0 0 1 [33563 rows x 3 columns] In [7]: Y.shape Out[7]: (33563, 3) In [10]: tok.index_word[250] Out[10]: 'реабилитац' In [11]: tok.index_word[154] Out[11]: 'инвалид' In [12]: tok.index_word[16] Out[12]: 'год'

воскресенье, 15 декабря 2019 г.

Ошибка размерности массива в Python

#python #python_3x #нейронные_сети #numpy #keras


Пишу нейронную сеть для распознавания цифр, вылезла ошибка - не могу разобраться
как изменить размерность массива, код ниже

import numpy as np
from keras.utils import np_utils
from keras.models import model_from_json
from keras.preprocessing import image
import matplotlib.pyplot as plt
%matplotlib inline

json_file = open("fully_mesh_network.json", "r")
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("fully_mesh_network.h5")

loaded_model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

img_path = '2.png'
img = image.load_img(img_path, target_size=(28,28), grayscale=True)

x = image.img_to_array(img)
x = 255 - x
x/= 255
x = np.expand_dims(x, axis = 0)

prediction = loaded_model.predict(x)
prediction = np_utils.categorical_probas_to_classes(prediction)
print(prediction)
---------------------------------------------------------------------------

ValueError: Error when checking : expected dense_1_input to have 2 dimensions, but
got array with shape (1, 28, 28, 1)

    


Ответы

Ответ 1



Судя по ошибке ваша модель ожидает 2D массив на входе. попробуйте так: x = x.reshape(28, 28) PS метод np_utils.categorical_probas_to_classes() - отсутствует в современных версиях Keras. Вместо него можно попробовать использовать метод: keras.utils.to_categorical()

воскресенье, 1 декабря 2019 г.

Как осуществить поиск объекта на изображении с помощью полносверточной нейронной сети

#python #нейронные_сети #keras


Здравствуйте, стоит задача поиска объекта с помощью полносверточной нейронной сети,
используя Keras, theano, на языке python. На данный момент используется вот такая конфигурация
сети: 

def create_encoding_layers():
    kernel = 3
    filter_size = 64
    pad = 1
    pool_size = 2
    return [
        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(filter_size, kernel, kernel, border_mode='valid'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size=(pool_size, pool_size)),

        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(32, kernel, kernel, border_mode='valid'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size=(pool_size, pool_size)),

        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(32, kernel, kernel, border_mode='valid'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size=(pool_size, pool_size)),

        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(64, kernel, kernel, border_mode='valid'),
        BatchNormalization(),
        Activation('relu'),
    ]
    def create_decoding_layers():
    kernel = 3
    filter_size = 64
    pad = 1
    pool_size = 2
    return[
        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(64, kernel, kernel, border_mode='valid'),
        BatchNormalization(),

        UpSampling2D(size=(pool_size,pool_size)),
        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(32, kernel, kernel, border_mode='valid'),
        BatchNormalization(),

        UpSampling2D(size=(pool_size,pool_size)),
        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(32, kernel, kernel, border_mode='valid'),
        BatchNormalization(),

        UpSampling2D(size=(pool_size,pool_size)),
        ZeroPadding2D(padding=(pad,pad)),
        Convolution2D(filter_size, kernel, kernel,     border_mode='valid'),
        BatchNormalization(),
        ZeroPadding2D(padding=(0,pad+1)),
    ]

    segnet_basic = models.Sequential()
    segnet_basic.add(Layer(input_shape=(120, 420, 1)))
    segnet_basic.encoding_layers = create_encoding_layers()
    for l in segnet_basic.encoding_layers:
        segnet_basic.add(l)
    segnet_basic.decoding_layers = create_decoding_layers()
    for l in segnet_basic.decoding_layers:
        segnet_basic.add(l)
    segnet_basic.add(Convolution2D(1, 1, 1, border_mode='valid',))
    segnet_basic.summary()
    segnet_basic.add(Reshape((120,420,1)))


На вход подается фотография и маска(область, где находится объект заполнена единицами,
а остальная область нулями). Как я понимаю, на выходе мы должны получить такую же маску.
Пробовал разные функции потерь. На выходе получается ерунда. Собственно вопрос: что
нужно исправить, чтобы получить на выходе аналогичную маску ? Какую функцию потерь
и  optimizer использовать? 
 На картинке пример работы уже обученной сети. image - изображение, которое подается
сети, label - ожидаемый результат, который я для вывода умножил на 255, result - то,
что выдает сеть.Так же умножил на 255 для вывода 

    


Ответы

Ответ 1



Исходя из того, что указано в вопросе, можно сделать выводы: Ваша НС, вероятно, переобучается. Это следует из того, что на train множестве Вы имеете хорошие результаты, а на тестовом -- никакие. Один из возможных вариантом -- это использование регуляризации. Кроме того, попробуйте использовать метод dropOut. Данная техника способствует уменьшению переобучения путём случайного исключения связей в НС. Вам необходимо делать cross-validation (cv). Данная процедура проводится для оценки модели и подбора параметров. Нас интересут оценка. В scikit-learn есть замечательные механизмы, позволяющие это делать. Один из вариантов cv (вам он подходит больше, так как ваша выборка маленькая) заключается в том, что исходное множество разбивается на 2 части (например): 0.3 - 0.7. Та часть, которая больше 0.7 является обучающим множеством. Та часть, которая меньше -- валидационном. Мы производим обучение на обучающем множестве. После чего проверяем наш результат на валидационном. Проделаем так много раз. Возьмите, для простоты 10. Всё зависит от дисперсии ответов и размера множества. Если cv не делать, то судить о модели никак нельзя. Ещё одной вероятной причиной переобучения является наличие большого количества слоёв в НС при необльшом количестве примеров. Для того, чтобы повысить число примеров, можно воспользоваться нарезкой изображений. Берём и режем каждое изображение на необшие области, сопостовимые с объектом интереса (желательно, чтобы области были больше объекта). Лучше резать картинку так, чтобы зоны ложились в нахлёст. Например, пусть исходная картика имеет размер 400х400. Порежем её на семплы 20х20. Будем передвигать окно 20х20 с шагом 10. Тогда получится, что каждое окно будет ложиться на предыдущее. Для каждого окна можно осуществлять предсказание, которое Вы хотели делать. Ещё одним возможным вариантом является вращение картинок на небольшие углы. Но данный вид трансформации может быть пагубным (в зависимости от задачи). Дальнейшие советы давать сложно, поскольку не видно всего множества, а также непонятна конечная цель задачи.

Ответ 2



В конфигурации Вашей сети на вход подается одно изображение формата (120, 420, 1). На выходе сети одно изображение такого же формата (120, 420, 1). Соответственно, чтобы научить эту (или другую) сеть строить из изображения маску, необходимо сеть обучить, то есть прогнать через нее большое количество пар (картинка, маска). Тогда в случае успешного обучения сеть будет уметь по картинке получать маску. Если просто загнать картинку в необученную сеть, на выходе разумеется будет ерунда. Функцию потерь в случае маски можно вполне брать стандартную вроде mse. Более эффективно в случае детектирования объектов таргетировать bounding box, а не маску и, соответственно, использовать box regression loss.

пятница, 7 июня 2019 г.

Сохранение лучшей модели

При обучении сети необходимо заранее указывать количество эпох обучения. При этом не обязательно, что сеть с каждой эпохой будет становиться лучше.
Можно ли организовать обучение сети таким образом, чтобы после каждой эпохи сравнивать получившуюся сеть с лучшей? Чтобы после того, как пройдет заданное количество эпох, была получена лучшая сеть за все время обучения, а не сеть после обучения на заданное количество эпох.


Ответ

Вы можете воспользоваться callbacks для сохранения лучшей модели и для ранней остановки (чтобы избежать бесполезных вычислений и ускорить время обучения модели):
from keras.callbacks import EarlyStopping, ModelCheckpoint
early_stop = EarlyStopping(monitor='val_acc', min_delta=0.0001, patience=5, verbose=1, mode='auto') chkpt = ModelCheckpoint(model_filename, monitor='val_loss', verbose=1, save_best_only=True, mode='auto') callbacks = [early_stop, chkpt]
hist = model.fit(x_train, y_train, batch_size=Batch_size, epochs=Epochs, validation_data=(x_val, y_val), callbacks=callbacks)

четверг, 16 мая 2019 г.

Какие могут быть пути улучшения обобщающей способности ИНС на базе Keras?

Несколько дней назад я создавал тему с похожим вопросом: Проблема с обучением сети в Keras: нет обобщающей способности сети, и там получил резонное замечание и совет. Решив попробовать поработать с данными, в которых информация не утрачена (нежели в прошлом топике), я собрал подобную ИНС, предварительно нормализовав данные (использование StandardScaler оказалось лучше MinMax).
Дано: База из 71 осциллограммы с 3002 отсчетами. Диапазон данных: от 0 до 10Е6. Данные векторы разбиты на обучающую выборку и тестовую (36 и 35).
Задача: входным векторам присваивать значения на выходе в виде определенного числа (от 30 до 100).
Ограничения: нет возможности получить огромный датасет (из тысяч векторов) и возможный максимум - сотня-полторы векторов.
Текущая конфигурация сети довольно неплохо обучается (в сравнении с предыдущей), однако проблема с обобщением результатов все также существует. Хоть результат и лучше он все еще не устраивает меня. Меняя конфигурации многослойного персептрона (число нейронов в слое, число слоев) мне не удавалось сильно изменять выходной результат (разве что, кроме времени обучения, что логично). Возможно я не подобрался к самой оптимальной структуре ИНС, но пока есть только это. Кстати да, функцию обучения выбирал методом научного тыка. Перепробовал разные методы и данный показал себя лучше всего.
Итак, отсюда у меня вопросы: Какие возможные пути изменения ИНС для улучшения результата? К сожалению я все еще новичок в этой области и знаком только с персептронами. Быть может вы сможете посоветовать какие-то другие типы сетей? Если после нормализации у меня диапазон значений вектора от -2 до 6, то как это влияет? На сколько мне известно, то на вход сети следует подавать данные в диапазоне [0 1] или [-1 1].
Код сети:
#загружаем файл с образами TRAIN_FILE="TRAIN30_100km.csv" TEST_FILE="TEST30_100km.csv"
# размер вектора img_rows, img_cols = 1, 3002
# Загружаем данные для обучения train_dataset = np.loadtxt(TRAIN_FILE, skiprows=0, dtype='int', delimiter=",") test_dataset = np.loadtxt(TEST_FILE, skiprows=0, dtype='int', delimiter=",")
# Выделяем данные для обучения X_train = train_dataset[:, 1:] X_test = test_dataset[:, 1:]
# нормализуем данные scaler = StandardScaler() x_train=scaler.fit_transform(X_train) x_test=scaler.fit_transform(X_test)
# Выделяем правильные ответы y_train = train_dataset[:,0] y_test = test_dataset[:,0]
# рисуем график нормализованного вектора и оригинального y10 = x_train[6, :] y11=X_train[6, :] plt.figure(figsize=(8, 8)) plt.plot(y10) plt.show() plt.figure(figsize=(8, 8)) plt.plot(y11) plt.show()
# Выделяем правильные ответы y_train = train_dataset[:,0] y_test = test_dataset[:,0]
model = Sequential()
model.add(Dense(10, input_dim=3002, activation="relu",kernel_regularizer=regularizers.l2(0.01))) model.add(Dense(15, activation='relu', kernel_regularizer=regularizers.l2(0.01))) model.add(Dense(5, activation='relu', kernel_regularizer=regularizers.l2(0.01))) model.add(Dense(5, activation='relu')) model.add(Dense(1)) model.compile( optimizer='Adagrad', loss="mse", metrics=['mae'])
print(model.summary()) model.fit(x_train, y_train, epochs=30, batch_size=1, verbose=2,validation_data=(x_test, y_test))
Epoch 30/30 - 0s - loss: 0.9548 - mean_absolute_error: 0.1053 - val_loss: 102.0822 - val_mean_absolute_error: 7.7214
mse, mae = model.evaluate(x_test, y_test, verbose=0) predictions=model.predict(x_test) print(predictions) # ответы (правильные 31 33 35 37) [20.31354 ] [18.931906] [21.085878] [20.537167]
Ссылка на датасет


Ответ

Немного подумав, решил упростить НС по-максимуму и получил лучшие показатели.
Архитектура:
model = Sequential() model.add(Dense(128, input_dim=3002, activation="relu", kernel_regularizer=l2(0.01))) model.add(BatchNormalization()) model.add(Dense(1)) model.compile( optimizer='Adagrad', loss="mse", metrics=['mae', 'mse']) hist = model.fit(x_train, y_train, epochs=300, batch_size=3, verbose=2,validation_data=(x_test, y_test), callbacks=callbacks)
вывод:
Epoch 00147: val_mean_squared_error did not improve from 13.76798 Epoch 148/300 - 0s - loss: 183.8615 - mean_absolute_error: 10.9775 - mean_squared_error: 180.3115 - val_loss: 23.7155 - val_mean_absolute_error: 3.2763 - val_mean _squared_error: 20.1659
Epoch 00148: val_mean_squared_error did not improve from 13.76798 Epoch 00148: early stopping
оценка:
In [206]: model = load_model(model_fn)
In [207]: model.evaluate(x_test, y_test, verbose=1) 18/18 [==============================] - 2s 135ms/step Out[207]: [17.30735206604004, 3.1715924739837646, 13.767986297607422]
сравнение тестового набора с предсказанными значениями:
In [208]: from sklearn.metrics import mean_absolute_error, mean_squared_error
In [209]: df = pd.DataFrame({'y_test':y_test.ravel(), 'y_pred':model.predict(x_test).ravel()})
In [210]: mean_squared_error(df['y_test'], df['y_pred']) Out[210]: 13.76798614917061
In [211]: mean_absolute_error(df['y_test'], df['y_pred']) Out[211]: 3.171592500474718
In [212]: df['abs_err'] = np.abs(df['y_test'] - df['y_pred'])
In [213]: df Out[213]: y_test y_pred abs_err 0 39.0 41.414223 2.414223 1 41.0 38.207268 2.792732 2 43.0 49.000561 6.000561 3 73.0 73.476303 0.476303 4 33.0 32.048149 0.951851 5 78.0 76.682877 1.317123 6 53.0 57.643074 4.643074 7 54.0 58.276382 4.276382 8 67.0 63.092651 3.907349 9 49.0 53.009842 4.009842 10 89.0 87.252930 1.747070 11 65.0 62.399197 2.600803 12 63.0 68.281502 5.281502 13 58.0 55.078934 2.921066 14 48.0 43.649544 4.350456 15 80.0 72.487808 7.512192 16 60.0 60.331455 0.331455 17 47.0 45.445320 1.554680
In [217]: df[['y_test','y_pred']].plot() Out[217]:

воскресенье, 14 апреля 2019 г.

Обучение нейронной сети теореме Пифагора

Хочу обучить НС теореме Пифагора. Всё вроде правильно сделал, нормализовал данные, модель правильная, а вот в чём ошибка не понятно..
import numpy as np
from keras.models import Sequential from keras.layers.core import Dense, Activation from keras.utils import np_utils
np.random.seed()
NB_EPOCH = 500 VERBOSE = 1
X_in = [[ 0 , 44 ], [ 0 , 18 ], [ 38 , 0 ], [ 48 , 14 ], [ 0 , 36 ], [ 14 , 0 ], [ 34 , 0 ], [ 0 , 0 ], [ 0 , 38 ], [ 32 , 0 ], [ 28 , 0 ], [ 36 , 0 ], [ 20 , 48 ], [ 0 , 6 ], [ 0 , 20 ], [ 0 , 42 ], [ 0 , 8 ], [ 24 , 32 ], [ 4 , 0 ], [ 6 , 8 ], [ 24 , 10 ], [ 0 , 22 ], [ 16 , 12 ], [ 30 , 40 ], [ 0 , 32 ], [ 0 , 32 ], [ 16 , 0 ], [ 48 , 20 ], [ 0 , 8 ], [ 32 , 0 ], [ 0 , 46 ], [ 0 , 22 ], [ 0 , 8 ], [ 10 , 24 ], [ 0 , 36 ], [ 14 , 0 ], [ 0 , 22 ], [ 42 , 0 ], [ 16 , 12 ], [ 40 , 30 ], [ 44 , 0 ], [ 40 , 0 ], [ 34 , 0 ], [ 0 , 32 ], [ 40 , 30 ], [ 32 , 0 ], [ 0 , 30 ], [ 24 , 18 ], [ 0 , 26 ], [ 22 , 0 ], [ 0 , 4 ], [ 16 , 0 ], [ 10 , 0 ], [ 0 , 32 ], [ 0 , 42 ], [ 2 , 0 ], [ 0 , 38 ], [ 32 , 24 ], [ 48 , 0 ], [ 20 , 0 ], [ 0 , 18 ], [ 0 , 38 ], [ 14 , 48 ], [ 40 , 42 ], [ 16 , 12 ], [ 26 , 0 ], [ 0 , 20 ], [ 40 , 30 ], [ 16 , 30 ], [ 36 , 48 ], [ 36 , 0 ], [ 18 , 24 ], [ 34 , 0 ], [ 16 , 0 ], [ 0 , 24 ], [ 0 , 24 ], [ 0 , 18 ], [ 38 , 0 ], [ 28 , 0 ], [ 0 , 34 ], [ 0 , 36 ], [ 24 , 32 ], [ 16 , 30 ], [ 40 , 30 ], [ 24 , 0 ], [ 0 , 14 ], [ 8 , 6 ], [ 12 , 0 ], [ 16 , 0 ], [ 16 , 30 ], [ 48 , 14 ], [ 0 , 30 ], [ 38 , 0 ], [ 38 , 0 ], [ 0 , 8 ], [ 36 , 48 ], [ 0 , 32 ], [ 10 , 24 ], [ 46 , 0 ], [ 24 , 10 ], [ 30 , 0 ], [ 0 , 48 ], [ 40 , 0 ], [ 42 , 0 ], [ 32 , 24 ], [ 32 , 0 ], [ 12 , 16 ], [ 0 , 4 ], [ 0 , 28 ], [ 32 , 0 ], [ 40 , 42 ], [ 46 , 0 ], [ 0 , 24 ], [ 30 , 16 ], [ 36 , 48 ], [ 40 , 0 ], [ 24 , 0 ], [ 0 , 22 ], [ 40 , 42 ], [ 10 , 24 ], [ 0 , 16 ], [ 14 , 48 ], [ 22 , 0 ], [ 0 , 22 ], [ 30 , 0 ], [ 0 , 2 ], [ 48 , 20 ], [ 6 , 0 ], [ 6 , 0 ], [ 28 , 0 ], [ 20 , 0 ], [ 0 , 40 ], [ 42 , 0 ], [ 48 , 36 ], [ 14 , 0 ], [ 10 , 24 ], [ 0 , 30 ], [ 48 , 20 ], [ 40 , 30 ], [ 0 , 0 ], [ 42 , 40 ], [ 0 , 48 ], [ 32 , 24 ]] X_answer = [[44] ,[18] ,[38] ,[50] ,[36] ,[14] ,[34] ,[0] ,[38] ,[32] ,[28] ,[36] ,[52] ,[6] ,[20] ,[42] ,[8] ,[40] ,[4] ,[10] ,[26] ,[22] ,[20] ,[50] ,[32] ,[32] ,[16] ,[52] ,[8] ,[32] ,[46] ,[22] ,[8] ,[26] ,[36] ,[14] ,[22] ,[42] ,[20] ,[50] ,[44] ,[40] ,[34] ,[32] ,[50] ,[32] ,[30] ,[30] ,[26] ,[22] ,[4] ,[16] ,[10] ,[32] ,[42] ,[2] ,[38] ,[40] ,[48] ,[20] ,[18] ,[38] ,[50] ,[58] ,[20] ,[26] ,[20] ,[50] ,[34] ,[60] ,[36] ,[30] ,[34] ,[16] ,[24] ,[24] ,[18] ,[38] ,[28] ,[34] ,[36] ,[40] ,[34] ,[50] ,[24] ,[14] ,[10] ,[12] ,[16] ,[34] ,[50] ,[30] ,[38] ,[38] ,[8] ,[60] ,[32] ,[26] ,[46] ,[26] ,[30] ,[48] ,[40] ,[42] ,[40] ,[32] ,[20] ,[4] ,[28] ,[32] ,[58] ,[46] ,[24] ,[34] ,[60] ,[40] ,[24] ,[22] ,[58] ,[26] ,[16] ,[50] ,[22] ,[22] ,[30] ,[2] ,[52] ,[6] ,[6] ,[28] ,[20] ,[40] ,[42] ,[60] ,[14] ,[26] ,[30] ,[52] ,[50] ,[0] ,[58] ,[48] ,[40]] X_in = np.asarray(X_in, dtype=np.float32) X_answer = np.asarray(X_answer, dtype=np.float32)
X_in /= np.amax(X_in) X_answer /= np.amax(X_answer)
model = Sequential() model.add(Dense(10, input_dim = 2, activation='relu')) model.add(Dense(10, activation='relu')) model.add(Dense(1, activation='softmax'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
history = model.fit(X_in, X_answer, epochs=NB_EPOCH, verbose=VERBOSE)
Что до 100 эпох, что до 500 один и тот же результат:
Epoch 1/100 143/143 [==============================] - 0s 2ms/step - loss: 0.2966 - acc: 0.0280 Epoch 2/100 143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280 Epoch 3/100 143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280 Epoch 4/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 5/100 143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280 Epoch 6/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 7/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 8/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 9/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 10/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 11/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 12/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 13/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 14/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 15/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 16/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 17/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 18/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 19/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 20/100 143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280 Epoch 21/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 22/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 23/100 143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280 Epoch 24/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 25/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 26/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 27/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 28/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 29/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 30/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 31/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 32/100 143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280 Epoch 33/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 34/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 35/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 36/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 37/100 143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280 Epoch 38/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 39/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 40/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 41/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 42/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 43/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 44/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 45/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 46/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 47/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 48/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 49/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 50/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 51/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 52/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 53/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 54/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 55/100 143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280 Epoch 56/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 57/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 58/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 59/100 143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280 Epoch 60/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 61/100 143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280 Epoch 62/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 63/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 64/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 65/100 143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280 Epoch 66/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 67/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 68/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 69/100 143/143 [==============================] - 0s 52us/step - loss: 0.2966 - acc: 0.0280 Epoch 70/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 71/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 72/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 73/100 143/143 [==============================] - 0s 39us/step - loss: 0.2966 - acc: 0.0280 Epoch 74/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 75/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 76/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 77/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 78/100 143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280 Epoch 79/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 80/100 143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280 Epoch 81/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 82/100 143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280 Epoch 83/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 84/100 143/143 [==============================] - 0s 35us/step - loss: 0.2966 - acc: 0.0280 Epoch 85/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 86/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 87/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 88/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 89/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 90/100 143/143 [==============================] - 0s 49us/step - loss: 0.2966 - acc: 0.0280 Epoch 91/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 92/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 93/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280 Epoch 94/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 95/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 96/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 97/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 98/100 143/143 [==============================] - 0s 45us/step - loss: 0.2966 - acc: 0.0280 Epoch 99/100 143/143 [==============================] - 0s 42us/step - loss: 0.2966 - acc: 0.0280 Epoch 100/100 143/143 [==============================] - 0s 38us/step - loss: 0.2966 - acc: 0.0280


Ответ

Как уже сказал @L.Murashov функция активации softmax применяется в задачах мультиклассовой классификации - она помогает посчитать вероятности принадлежности образца каждому из классов.
Есть еще несколько моментов, на которые стоит обратить внимание:
В обучающей выборке слишком много (около половины) нулевых значений - это вырожденный случай для теоремы Пифагора, когда одна из сторон треугольника имеет нулевую длину. Для того, чтобы лучше обучить модель можно выборку взять побольше - в вашем случае не проблема сгенерировать столько данных сколько нужно. Для данной (простой) задачи хватит одного скрытого слоя В качестве функции активации выходного слоя можно использовать linear В качестве функции потери и метрики можно выбрать mean_squared_error

Пример:
import numpy as np from keras.models import Sequential from keras.layers.core import Dense, Activation
N = 5000 np.random.seed(1234) X = np.random.randint(0, 50, size=(N,2)) y = np.linalg.norm(X, axis=1)
NB_EPOCHS = 100 VERBOSE = 1
model = Sequential() model.add(Dense(20, input_dim = 2, activation='relu')) model.add(Dense(1, activation='linear')) model.compile(loss='mse', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=NB_EPOCHS, verbose=VERBOSE)
Обучение:
... 5000/5000 [==============================] - 0s 22us/step - loss: 0.0057 - mean_squared_error: 0.0057 Epoch 98/100 5000/5000 [==============================] - 0s 22us/step - loss: 0.0048 - mean_squared_error: 0.0048 Epoch 99/100 5000/5000 [==============================] - 0s 22us/step - loss: 0.0045 - mean_squared_error: 0.0045 Epoch 100/100 5000/5000 [==============================] - 0s 22us/step - loss: 0.0043 - mean_squared_error: 0.0043 Out[70]:
Предсказание:
In [71]: model.predict(np.array([[3,4], [10,10], [5,6]])) Out[71]: array([[ 5.018393], [14.130004], [ 7.841759]], dtype=float32)

понедельник, 11 марта 2019 г.

Ошибка размерности массива в Python

Пишу нейронную сеть для распознавания цифр, вылезла ошибка - не могу разобраться как изменить размерность массива, код ниже
import numpy as np from keras.utils import np_utils from keras.models import model_from_json from keras.preprocessing import image import matplotlib.pyplot as plt %matplotlib inline
json_file = open("fully_mesh_network.json", "r") loaded_model_json = json_file.read() json_file.close() loaded_model = model_from_json(loaded_model_json) loaded_model.load_weights("fully_mesh_network.h5")
loaded_model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
img_path = '2.png' img = image.load_img(img_path, target_size=(28,28), grayscale=True)
x = image.img_to_array(img) x = 255 - x x/= 255 x = np.expand_dims(x, axis = 0)
prediction = loaded_model.predict(x) prediction = np_utils.categorical_probas_to_classes(prediction) print(prediction) ---------------------------------------------------------------------------
ValueError: Error when checking : expected dense_1_input to have 2 dimensions, but got array with shape (1, 28, 28, 1)


Ответ

Судя по ошибке ваша модель ожидает 2D массив на входе.
попробуйте так:
x = x.reshape(28, 28)
PS метод np_utils.categorical_probas_to_classes() - отсутствует в современных версиях Keras. Вместо него можно попробовать использовать метод: keras.utils.to_categorical()

суббота, 6 октября 2018 г.

Как осуществить поиск объекта на изображении с помощью полносверточной нейронной сети

Здравствуйте, стоит задача поиска объекта с помощью полносверточной нейронной сети, используя Keras, theano, на языке python. На данный момент используется вот такая конфигурация сети:
def create_encoding_layers(): kernel = 3 filter_size = 64 pad = 1 pool_size = 2 return [ ZeroPadding2D(padding=(pad,pad)), Convolution2D(filter_size, kernel, kernel, border_mode='valid'), BatchNormalization(), Activation('relu'), MaxPooling2D(pool_size=(pool_size, pool_size)),
ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, kernel, kernel, border_mode='valid'), BatchNormalization(), Activation('relu'), MaxPooling2D(pool_size=(pool_size, pool_size)),
ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, kernel, kernel, border_mode='valid'), BatchNormalization(), Activation('relu'), MaxPooling2D(pool_size=(pool_size, pool_size)),
ZeroPadding2D(padding=(pad,pad)), Convolution2D(64, kernel, kernel, border_mode='valid'), BatchNormalization(), Activation('relu'), ] def create_decoding_layers(): kernel = 3 filter_size = 64 pad = 1 pool_size = 2 return[ ZeroPadding2D(padding=(pad,pad)), Convolution2D(64, kernel, kernel, border_mode='valid'), BatchNormalization(),
UpSampling2D(size=(pool_size,pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, kernel, kernel, border_mode='valid'), BatchNormalization(),
UpSampling2D(size=(pool_size,pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, kernel, kernel, border_mode='valid'), BatchNormalization(),
UpSampling2D(size=(pool_size,pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(filter_size, kernel, kernel, border_mode='valid'), BatchNormalization(), ZeroPadding2D(padding=(0,pad+1)), ]
segnet_basic = models.Sequential() segnet_basic.add(Layer(input_shape=(120, 420, 1))) segnet_basic.encoding_layers = create_encoding_layers() for l in segnet_basic.encoding_layers: segnet_basic.add(l) segnet_basic.decoding_layers = create_decoding_layers() for l in segnet_basic.decoding_layers: segnet_basic.add(l) segnet_basic.add(Convolution2D(1, 1, 1, border_mode='valid',)) segnet_basic.summary() segnet_basic.add(Reshape((120,420,1)))
На вход подается фотография и маска(область, где находится объект заполнена единицами, а остальная область нулями). Как я понимаю, на выходе мы должны получить такую же маску. Пробовал разные функции потерь. На выходе получается ерунда. Собственно вопрос: что нужно исправить, чтобы получить на выходе аналогичную маску ? Какую функцию потерь и optimizer использовать? На картинке пример работы уже обученной сети. image - изображение, которое подается сети, label - ожидаемый результат, который я для вывода умножил на 255, result - то, что выдает сеть.Так же умножил на 255 для вывода


Ответ

Исходя из того, что указано в вопросе на текущий момент, можно сделать выводы:
Ваша НС, вероятно, переобучается. Это следует из того, что на train множестве Вы имеете хорошие результаты, а на тестовом -- никакие. Один из возможных вариантом -- это использование регуляризации. Кроме того, попробуйте использовать метод dropOut. Данная техника способствует уменьшению переобучения путём случайного исключения связей в НС. Вам необходимо делать cross-validation (cv). Данная процедура проводится для оценки модели и подбора параметров. Нас интересут оценка. В scikit-learn есть замечательные механизмы, позволяющие это делать. Один из вариантов cv (вам он подходит больше, так как ваша выборка маленькая) заключается в том, что исходное множество разбивается на 2 части (например): 0.3 - 0.7. Та часть, которая больше 0.7 является обучающим множеством. Та часть, которая меньше -- валидационном. Мы производим обучение на обучающем множестве. После чего проверяем наш результат на валидационном. Проделаем так много раз. Возьмите, для простоты 10. Всё зависит от дисперсии ответов и размера множества. Если cv не делать, то судить о модели никак нельзя. Ещё одной вероятной причиной переобучения является наличие большого количества слоёв в НС при необльшом количестве примеров. Для того, чтобы повысить число примеров, можно воспользоваться нарезкой изображений. Берём и режем каждое изображение на необшие области, сопостовимые с объектом интереса (желательно, чтобы области были больше объекта). Лучше резать картинку так, чтобы зоны ложились в нахлёст. Например, пусть исходная картика имеет размер 400х400. Порежем её на семплы 20х20. Будем передвигать окно 20х20 с шагом 10. Тогда получится, что каждое окно будет ложиться на предыдущее. Для каждого окна можно осуществлять предсказание, которое Вы хотели делать. Ещё одним возможным вариантом является вращение картинок на небольшие углы. Но данный вид трансформации может быть пагубным (в зависимости от задачи).
Дальнейшие советы давать сложно, поскольку не видно всего множества, а также непонятна конечная цель задачи.