Может ли авто-кодировщик кодировать новый вектор без повторного обучения sh? - PullRequest
1 голос
/ 17 апреля 2020

Вот простой автоэнкодер для кодирования 3 векторов измерения 1x3: [1,2,3],[1,2,3],[100,200,500] до 1x1:

epochs = 1000
from pylab import plt
plt.style.use('seaborn')
import torch.utils.data as data_utils
import torch
import torchvision
import torch.nn as nn
from torch.autograd import Variable

cuda = torch.cuda.is_available()
FloatTensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor
import numpy as np
import pandas as pd
import datetime as dt


features = torch.tensor(np.array([ [1,2,3],[1,2,3],[100,200,500] ]))

print(features)

batch = 1
data_loader = torch.utils.data.DataLoader(features, batch_size=2, shuffle=False)

encoder = nn.Sequential(nn.Linear(3,batch), nn.Sigmoid())
decoder = nn.Sequential(nn.Linear(batch,3), nn.Sigmoid())
autoencoder = nn.Sequential(encoder, decoder)

optimizer = torch.optim.Adam(params=autoencoder.parameters(), lr=0.001)

encoded_images = []
for i in range(epochs):
    for j, images in enumerate(data_loader):
    #     images = images.view(images.size(0), -1) 
        images = Variable(images).type(FloatTensor)
        optimizer.zero_grad()
        reconstructions = autoencoder(images)
        loss = torch.dist(images, reconstructions)
        loss.backward()
        optimizer.step()

#     encoded_images.append(encoder(images))

# print(decoder(torch.tensor(np.array([1,2,3])).type(FloatTensor)))

encoded_images = []
for j, images in enumerate(data_loader):
    images = images.view(images.size(0), -1) 
    images = Variable(images).type(FloatTensor)

    encoded_images.append(encoder(images))

Переменная encoded_images - это массив размера 3, где каждая запись массива представляет уменьшенную размерность массива feature:

[tensor([[0.9972],
         [0.9972]], grad_fn=<SigmoidBackward>),
 tensor([[1.]], grad_fn=<SigmoidBackward>)]

Чтобы определить сходство новой функции, например, [1,1,1], требуется ли переподготовка сети или могут существующая обученная конфигурация / веса сети «загружен» таким образом, что новый вектор может быть закодирован без необходимости переобучения сети после sh?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

Извините, но ваш код беспорядок ... И если это просто для демонстрации идеи автоэнкодера (здесь у вас просто есть координаты X, Y, Z, а вы называете ее image), то она выбрана довольно плохо.

Не в пути: Если это изображение, вы не сможете его закодировать как один пиксель, это требует немного большей сложности.

Исходный код

Вот простой автокодер для кодирования 3 векторов измерения 1x3: [1,2,3], [1,2,3], [100,200,500] до 1x1

true только в этом случае, поскольку у вас есть пакет 3 элементов (в то время как вы назвали batch out_features сети!). Их размеры не 1x3, а просто 3. Вот Минимальный воспроизводимый пример с комментарием:

import torch

# Rows are batches, there could be 3, there could be a thousand
data = torch.tensor([[1, 2, 3], [1, 2, 3], [100, 200, 500]]).float()

# 3 input features, columns of data
encoder = torch.nn.Sequential(torch.nn.Linear(3, 1), torch.nn.Sigmoid())
decoder = torch.nn.Sequential(torch.nn.Linear(1, 3), torch.nn.Sigmoid())

autoencoder = torch.nn.Sequential(encoder, decoder)

optimizer = torch.optim.Adam(params=autoencoder.parameters(), lr=0.001)

epochs = 10000

for i in range(epochs):
    optimizer.zero_grad()
    reconstructions = autoencoder(data)
    loss = torch.dist(data, reconstructions)
    loss.backward()
    optimizer.step()
    # Print loss every 100 epoochs
    if i % 100 == 0:
        print(loss)

Будет ли это работать?

Этот более интересный. В принципе, если ваша нейронная сеть обучена, вам не нужно переучивать ее, чтобы включить пример, который она ранее не видела (поскольку цель нейронной сети - выучить некоторые шаблоны для решения задачи).

В вашем случае это не будет.

Почему это не сработает?

Прежде всего, у вас есть сигмовидная активация в decoder, которая ограничивает выходной диапазон [0, 1]. Вы пытаетесь предсказать данные, которые находятся за пределами этого диапазона, поэтому это невозможно.

Без выполнения я могу сказать вам, к чему приведет потеря этого примера go по отношению к (со всеми весами, равными +inf). Все прогнозы всегда будут [1, 1, 1] (или как можно ближе к нему), так как это значение меньше всего портит сеть, поэтому вам просто нужно вычислить расстояние каждого vector в данных до [1, 1, 1]. Здесь потеря застряла в районе 546.2719. Веса и уклоны составляют около 1041 * (что довольно много для сигмовидной кишки) после 100000 эпох. Ваши значения могут отличаться, но тренд ясен (хотя он остановится, поскольку 10 довольно близко к 1, когда вы наберете sh с sigmoid).

Удаление torch.nn.Sigmoid из decoder

Что если мы удалим torch.nn.Sigmoid() из decoder? Он научится почти идеально восстанавливать только ваши 3 примера , с потерей 0.002 после "только" 500000 эпох:

Вот выученные веса decoder:

tensor([[ 99.0000],
        [198.0000],
        [496.9999]], requires_grad=True)

А вот bias:

tensor([1.0000, 2.0000, 2.9999])

А вот выход encoder для каждого примера:

tensor([[2.2822e-13],
        [2.2822e-13],
        [1.0000e+00]])

Анализ результатов

Ваша сеть узнала только то, что вы сказали ей изучать, а это ... величина (+ умный bias хакер).

[1, 2, 3 ] vector

Пример [1, 2, 3] (повторяется дважды). его кодирование - 2e-13 и идет к нулю, поэтому мы предположим, что оно равно нулю.

Теперь, умножив 0 на все веса, вы все равно получите ноль. Добавьте bias, что составляет [1.0, 2.0, 2.99999], и вы волшебным образом восстановите свой вход.

[100, 200, 500] vector

Вы, вероятно, можете видеть, куда он идет.

Кодированное значение равно 1.0, при умножении на decoder веса мы получаем [99.0, 198.0, 497.0]. Добавьте bias к нему и вуаля, мы получим наш [100.0, 200.0, 500.0].

[1, 1, 1] вектор

В вашем случае это, очевидно, не будет работать как величина [1, 1, 1] действительно маленький, следовательно, он будет закодирован как zero и реконструирован как [1, 2, 3].

Удаление torch.nn.Sigmoid из encoder

Немного вне топики c, но когда вы удаляете сигмоид из кодировщика, он не сможет выучить этот шаблон так же легко. Причина в том, что сеть должна быть более консервативной с весами (поскольку они не будут раздавлены). Вам придется понизить скорость обучения (желательно постоянно снижать ее в процессе обучения), поскольку в какой-то момент она становится нестабильной (при попытке достичь «идеального места»).

Сходство обучения

Трудно (по крайней мере, для сети) определить «подобное» в этом случае. [1, 2, 3] похоже на [3, 2, 1]? Он не имеет понятия различных размеров и должен объединить эти три числа в единое значение (позднее использованное для реконструкции).

Как продемонстрировано, он, вероятно, изучит некоторые неявные шаблоны в ваших данных, которые будут хороши в восстановлении "хотя бы чего-то", но не найдет общий шаблон, который вы ищете. Тем не менее, это зависит от ваших данных и их свойств, но я бы вообще не стал спорить, и я думаю, что его возможности обобщения были бы плохими.

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

Если вам нужно сходство измерений (и это не просто мысленный эксперимент), у вас есть много "созданных человеком" вещей, таких как p-norm, некоторые кодировки (они также измеряют подобие, но по-другому), поэтому лучше для go для этого ИМО.

0 голосов
/ 22 апреля 2020

Ваш тестовый вектор / функция [1,1,1] имеет тот же размер, что и входные данные. И, следовательно, могут быть переданы через нейронную сеть, чтобы получить представление / кодирование. Поэтому не требуется вносить какие-либо изменения в параметры или конфигурацию сети.


Будет ли он работать верно?

Это очень интересный вопрос, и ответ: «это зависит». Трудно сделать какие-либо гарантии для изучения функции общего сходства только из трех входов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...