Практическое задание №5
1. Запустите jupyter notebook и создайте тетрадку.
2. Импортируйте следующие модули и загрузите набор данных lfw
from lfw_dataset import fetch_lfw_dataset
from sklearn.model_selection import train_test_split
X, attr = fetch_lfw_dataset(use_raw=True,dimx=38,dimy=38)
X = X.astype('float32') / 256.0
X_train, X_test = train_test_split(X, test_size=0.1,random_state=42)
3. Создайте автокодировщик, сложив несколько слоев. В частности, ваш кодер и декодер должны иметь глубину не менее 3-х слоев каждый. Вы можете использовать любую нелинейность, какую захотите, и любое количество скрытых нейронов в слоях:
def build_deep_autoencoder(img_shape,code_size=32):
encoder = keras.models.Sequential()
encoder.add(L.InputLayer(img_shape))
<Your code: define encoder as per instructions above>
decoder = keras.models.Sequential()
decoder.add(L.InputLayer((code_size,)))
<Your code: define encoder as per instructions above>
4. Обучите получившиеся модели:
encoder,decoder = build_deep_autoencoder(img_shape,code_size=32)
reconstruction = decoder(code)
autoencoder = keras.models.Model(inp,reconstruction)
autoencoder.compile('adamax','mse')
autoencoder.fit(x=X_train,y=X_train,epochs=32,
validation_data=[X_test,X_test])
5. Протестируйте модели и убедитесь в том, что:
a. Модель сошлась. Некоторые архитектуры нуждаются в более чем 32 эпохах, чтобы сходиться. Они могут сильно колебаться, но в конечном итоге они станут достаточно хорошими. Вы можете тренировать свою сеть столько времени, сколько хотите.
b. Если вы обучаете модель из более чем 100 слоев и все еще не проходит порог, нужно начать с небольшого количества слоев (1-2) и увеличивать сложность модели небольшими шагами.
c. Вы используете любую комбинацию слоев (включая свертки, нормализацию и т.д.)
d. Используете следующий код для тестирования модели:
reconstruction_mse = autoencoder.evaluate(X_test,X_test,verbose=0)
assert reconstruction_mse <= 0.005, "Compression is too lossy. See tips below."
assert len(encoder.output_shape)==2 and encoder.output_shape[1]==32, "Make sure encoder has code_size units"
print("Final MSE:", reconstruction_mse)
visualize(img,encoder,decoder)
6. Превратите получившуюся модель в шумоподавляющий автоэнкодер. Cохранив модельную архитектуру, измените способ ее обучения. Существует много стратегий применения шума. Мы реализуем два популярных: добавление гауссовского шума и использование dropout:
a. Реализуйте добавление гауссовского шума:
def apply_gaussian_noise(X,sigma=0.1):
adds noise from normal distribution with standard deviation sigma
:param X: image tensor of shape [batch,height,width,3]
b. Тестирование шума:
theoretical_std = (X[:100].std()**2 + 0.5**2)**.5
our_std = apply_gaussian_noise(X[:100],sigma=0.5).std()
assert abs(theoretical_std - our_std) < 0.01, "Standard deviation does not match it's required value. Make sure you use sigma as std."
assert abs(apply_gaussian_noise(X[:100],sigma=0.5).mean() - X[:100].mean()) < 0.01, "Mean has changed. Please add zero-mean noise"
7. Автокодировщик имеет ряд удивительных побочных эффектов. Посмотрите на это в действии. Подавая на вход изображение, найдите похожие изображения в скрытом пространстве. Чтобы ускорить процесс поиска, используйте локально-чувствительное хеширование поверх закодированных векторов. Используйте реализацию scikit-learn для простоты. В практическом сценарии вы можете использовать специализированные библиотеки для повышения производительности и настройки:
a. Внедрите функцию для нахождения похожих изображений
def get_similar(image, n_neighbors=5):
assert image.ndim==3,"image must be [batch,height,width,3]"
code = encoder.predict(image[None])
(distances,),(idx,) = lshf.kneighbors(code,n_neighbors=n_neighbors)
b. Внедрите функцию для отображения похожих изображений
distances,neighbors = get_similar(image,n_neighbors=11)
plt.title("Dist=%.3f"%distances[i])
8. Задачи для самостоятельной работы:
a. Увеличить точность полученной модели.
b. Реализуйте «Уменьшенную / ускоренную версию», с подробным анализом результатов