Практикум на ЭВМ (317)/Autoencoder
Материал из MachineLearning.
Строка 3: | Строка 3: | ||
В этом задании Вам предстоит реализовать нейросетевой алгоритм сокращения размерности данных, известный как автокодировщик ([http://en.wikipedia.org/wiki/Autoencoder autoencoder]). Его нужно настроить на базе изображений рукописных цифр [http://yann.lecun.com/exdb/mnist/ MNIST]. Обратите внимание, что нейросети обучаются значительное время. | В этом задании Вам предстоит реализовать нейросетевой алгоритм сокращения размерности данных, известный как автокодировщик ([http://en.wikipedia.org/wiki/Autoencoder autoencoder]). Его нужно настроить на базе изображений рукописных цифр [http://yann.lecun.com/exdb/mnist/ MNIST]. Обратите внимание, что нейросети обучаются значительное время. | ||
- | == Цели == | + | == Цели задания == |
# Познакомиться с задачей сокращения размерности данных (сжатия с потерями). | # Познакомиться с задачей сокращения размерности данных (сжатия с потерями). | ||
# Понять, какие практические проблемы возникают при обучении искусственных нейронных сетей. | # Понять, какие практические проблемы возникают при обучении искусственных нейронных сетей. | ||
- | # Усвоить принципы глубинного обучения. | + | # Усвоить некоторые принципы глубинного обучения (deep learning). |
# Закрепить навыки манипуляции с матрицами. | # Закрепить навыки манипуляции с матрицами. | ||
== Бэкграунд == | == Бэкграунд == | ||
+ | Искусственная нейронная сеть — достаточно мощная модель, используемая для решения различных задач машинного обучения. Классические алгоритмы машинного обучения (например, основанные на линейных моделях) пытаются отделить зависимости, действительно присутствующие в данных, от шума. При этом сами эти зависимости предполагаются достаточно простыми. В задачах, которые принято относить к искусственному интеллекту, данных значительно больше, поэтому шум представляет меньшую проблему, но зависимости в данных более сложные. Для решения подобных практических задач бывает полезно использовать нейросети. | ||
- | + | Функции потерь, которые нужно оптимизировать при обучении многослойных нейронных сетей невыпуклы и как правило содержат плато и локальные минимумы, что делает их оптимизацию неприятной. Найти глобальный минимум такой функции практически невозможно. Однако на практике это и не нужно: достаточно найти хороший локальный минимум. При этом результат обучения сильно зависит от инициализации и используемого метода оптимизации (в чём Вам предстоит убедиться), что делает его трудновоспроизводимым. На практике при обучении приходится экспериментировать и применять эвристики. Эти недостатки приходится приносить в жертву способности находить нелинейные зависимости в больших данных. | |
- | + | ||
- | + | В истории нейросетей всплески энтузиазма сменялись разочарованиями. Последнее разочаровние было во второй половине 90х и 00х годах, когда им на смену пришли модели, которые не требовали таких больших вычислительных ресурсов для оптимизации и аккуратной инициализации. Однако в конце 00х возрос интерес к [http://en.wikipedia.org/wiki/Big_data большим данным] и стали доступнее кластеры, что позволило обучать сложные модели. Также возникла парадигма глубинного обучения ([http://en.wikipedia.org/wiki/Deep_learning deep learning]), в рамках которой появились методы стабильной инициализации весов. Это возродило интерес к нейросетям. | |
- | + | ||
+ | Одна из идей глубинного обучения заключается в следующем. Чтобы избежать переобучения, нужно сначала сократить размерность данных (игнорируя метки классов), а затем уже обучаться на данных низкой размерности. Первый этап может заменять ручное извлечение признаков, поэтому эту идею называют обучением признаков (feature learning). Классические методы обучения без учителя либо линейные (например, [[метод главных компонент]], PCA), либо локальные ([[кластеризация]]). Автокодировщик преобразует данные, учитывая глобальные зависимости, как PCA, но при этом нелинейный. Он решает ту же задачу: преобразует данные высокой размерности в данные низкой размерности, пытаясь «нащупать» многообразие, в котором лежат данные. Восстановленные данные должны быть максимально близки к исходным данным большой размерности. | ||
== Данные == | == Данные == | ||
Строка 21: | Строка 23: | ||
* качаем отсюда: http://yann.lecun.com/exdb/mnist/ | * качаем отсюда: http://yann.lecun.com/exdb/mnist/ | ||
* конвертер от Салахутдинова: http://www.sciencemag.org/content/suppl/2006/08/04/313.5786.504.DC1/1127647code_tar.zip (или дать уже сконвертированные) | * конвертер от Салахутдинова: http://www.sciencemag.org/content/suppl/2006/08/04/313.5786.504.DC1/1127647code_tar.zip (или дать уже сконвертированные) | ||
- | * отображение: <pre>imshow(reshape(digitdata(1,:), 28,28)')</pre> (транспонирование, | + | * отображение: <pre>imshow(reshape(digitdata(1,:), 28,28)')</pre> (транспонирование, так как записаны по строкам) |
== Детали задания == | == Детали задания == | ||
- | * использование кросс-энтропии при обучении ( | + | * использование кросс-энтропии при обучении (бонус — MSE) |
- | * | + | * регуляризация — L2 (weight decay) и gaussian noise |
== Мои результаты == | == Мои результаты == | ||
- | * MNIST, only 0, PCA-30: MSE=9.0 | + | * MNIST, only 0, PCA-30: MSE=9.0 |
* MNIST, only 01, PCA-30: MSE=7.3 | * MNIST, only 01, PCA-30: MSE=7.3 | ||
* MNIST, all-dig, PCA-30: MSE=14.2 | * MNIST, all-dig, PCA-30: MSE=14.2 | ||
- | * MNIST, only 0, PCA-18: MSE=13.0 | + | * MNIST, only 0, PCA-18: MSE=13.0 |
* MNIST, only 1, PCA-18: MSE=3.7 | * MNIST, only 1, PCA-18: MSE=3.7 | ||
* MNIST, only 01, PCA-18: MSE=10.6 | * MNIST, only 01, PCA-18: MSE=10.6 | ||
* MNIST, all-dig, PCA-18: MSE=20.0 | * MNIST, all-dig, PCA-18: MSE=20.0 | ||
- | * MNIST, only 0, autoenc-st0b5e10: MSE=50.0 (averages everything) | + | * MNIST, only 0, autoenc-st0b5e10: MSE=50.0 (averages everything) // 5 batches, 10 epochs (default: targ-CE, opt-CG) |
* MNIST, only 0, autoenc-stNorm(0,0.3)b5e1000: MSE=12.6 (continues optimizing) | * MNIST, only 0, autoenc-stNorm(0,0.3)b5e1000: MSE=12.6 (continues optimizing) | ||
* MNIST, only 0, autoenc-stNorm(0,0.3)Tie-b5e400: MSE=16.0, 2-3 hours // seems no difference from the previous case | * MNIST, only 0, autoenc-stNorm(0,0.3)Tie-b5e400: MSE=16.0, 2-3 hours // seems no difference from the previous case | ||
* MNIST, only 0, autoenc-stNorm(0,0.3[*2,4])Tie-b5e400: MSE=23.4 | * MNIST, only 0, autoenc-stNorm(0,0.3[*2,4])Tie-b5e400: MSE=23.4 | ||
- | * MNIST, only 0, autoenc-stNorm(0,0.2)-b5e100,targ-MSE: MSE=55.0, (continues optimizing, diverse) | + | * MNIST, only 0, autoenc-stNorm(0,0.2)-b5e100,targ-MSE: MSE=55.0, (continues optimizing, diverse) // slower, but okay |
* could not make stochastic gradient find non-trivial optimum | * could not make stochastic gradient find non-trivial optimum | ||
* MNIST, only 0, autoenc-LeCunInitTanh(Last)Mean-b5e300,targCE: MSE=131.8 | * MNIST, only 0, autoenc-LeCunInitTanh(Last)Mean-b5e300,targCE: MSE=131.8 | ||
Строка 49: | Строка 51: | ||
* MNIST, only 0, pretrain-tiedw-stNorm(0,0.3)-stoch-b150: MSE1(e200): 1.6, MSE2(e500): 4.2, MSE3(e200): 2.3, MSE4(e200): 4.7. Backprop, 500it: MSE=3.0 // 2 hours | * MNIST, only 0, pretrain-tiedw-stNorm(0,0.3)-stoch-b150: MSE1(e200): 1.6, MSE2(e500): 4.2, MSE3(e200): 2.3, MSE4(e200): 4.7. Backprop, 500it: MSE=3.0 // 2 hours | ||
- | * MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3), targ-MSE, arch-sigm+1e-4(except-linear,last): | + | * MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3), targ-MSE, arch-sigm+1e-4(except-linear, last): // 630 s |
** level1: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=3.2. | ** level1: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=3.2. | ||
** level2: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=7.3. | ** level2: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=7.3. | ||
** level3: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=4.1. | ** level3: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=4.1. | ||
** level4: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=6.0. | ** level4: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=6.0. | ||
- | ** backprop: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=8.0. | + | ** backprop: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=8.0. // 630 s |
- | * MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3), targ-Xentropy, arch-sigm: | + | * MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3), targ-Xentropy, arch-sigm: // 730 s |
** level1: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=1.7. | ** level1: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=1.7. | ||
** level2: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=5.3. | ** level2: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=5.3. | ||
** level3: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=2.5. | ** level3: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=2.5. | ||
** level4: 10ep, momentum=0.97, nbatches=1500, step=0.01*(k+1)(-1/4), MSE=7.4. | ** level4: 10ep, momentum=0.97, nbatches=1500, step=0.01*(k+1)(-1/4), MSE=7.4. | ||
- | ** backprop: 3ep, momentum=0.97, nbatches=1500, step=0.1*(k+1)(-1/4), MSE=8.7. | + | ** backprop: 3ep, momentum=0.97, nbatches=1500, step=0.1*(k+1)(-1/4), MSE=8.7. // 645 s |
+ | |||
+ | * MNIST, all-dig, backprop train, stNorm(0,0.3), targ-Xentropy, arch-sigm, 30ep, momentum=0.97, nbatches=1500, step=0.1*(k+1)(-1/4), MSE=8.2, // 6280 s |
Версия 16:29, 21 февраля 2013
Это черновик задания. Не сто́ит приступать к его выполнению до официального релиза. |
В этом задании Вам предстоит реализовать нейросетевой алгоритм сокращения размерности данных, известный как автокодировщик (autoencoder). Его нужно настроить на базе изображений рукописных цифр MNIST. Обратите внимание, что нейросети обучаются значительное время.
Содержание |
Цели задания
- Познакомиться с задачей сокращения размерности данных (сжатия с потерями).
- Понять, какие практические проблемы возникают при обучении искусственных нейронных сетей.
- Усвоить некоторые принципы глубинного обучения (deep learning).
- Закрепить навыки манипуляции с матрицами.
Бэкграунд
Искусственная нейронная сеть — достаточно мощная модель, используемая для решения различных задач машинного обучения. Классические алгоритмы машинного обучения (например, основанные на линейных моделях) пытаются отделить зависимости, действительно присутствующие в данных, от шума. При этом сами эти зависимости предполагаются достаточно простыми. В задачах, которые принято относить к искусственному интеллекту, данных значительно больше, поэтому шум представляет меньшую проблему, но зависимости в данных более сложные. Для решения подобных практических задач бывает полезно использовать нейросети.
Функции потерь, которые нужно оптимизировать при обучении многослойных нейронных сетей невыпуклы и как правило содержат плато и локальные минимумы, что делает их оптимизацию неприятной. Найти глобальный минимум такой функции практически невозможно. Однако на практике это и не нужно: достаточно найти хороший локальный минимум. При этом результат обучения сильно зависит от инициализации и используемого метода оптимизации (в чём Вам предстоит убедиться), что делает его трудновоспроизводимым. На практике при обучении приходится экспериментировать и применять эвристики. Эти недостатки приходится приносить в жертву способности находить нелинейные зависимости в больших данных.
В истории нейросетей всплески энтузиазма сменялись разочарованиями. Последнее разочаровние было во второй половине 90х и 00х годах, когда им на смену пришли модели, которые не требовали таких больших вычислительных ресурсов для оптимизации и аккуратной инициализации. Однако в конце 00х возрос интерес к большим данным и стали доступнее кластеры, что позволило обучать сложные модели. Также возникла парадигма глубинного обучения (deep learning), в рамках которой появились методы стабильной инициализации весов. Это возродило интерес к нейросетям.
Одна из идей глубинного обучения заключается в следующем. Чтобы избежать переобучения, нужно сначала сократить размерность данных (игнорируя метки классов), а затем уже обучаться на данных низкой размерности. Первый этап может заменять ручное извлечение признаков, поэтому эту идею называют обучением признаков (feature learning). Классические методы обучения без учителя либо линейные (например, метод главных компонент, PCA), либо локальные (кластеризация). Автокодировщик преобразует данные, учитывая глобальные зависимости, как PCA, но при этом нелинейный. Он решает ту же задачу: преобразует данные высокой размерности в данные низкой размерности, пытаясь «нащупать» многообразие, в котором лежат данные. Восстановленные данные должны быть максимально близки к исходным данным большой размерности.
Данные
MNIST:
- качаем отсюда: http://yann.lecun.com/exdb/mnist/
- конвертер от Салахутдинова: http://www.sciencemag.org/content/suppl/2006/08/04/313.5786.504.DC1/1127647code_tar.zip (или дать уже сконвертированные)
- отображение:
imshow(reshape(digitdata(1,:), 28,28)')
(транспонирование, так как записаны по строкам)
Детали задания
- использование кросс-энтропии при обучении (бонус — MSE)
- регуляризация — L2 (weight decay) и gaussian noise
Мои результаты
- MNIST, only 0, PCA-30: MSE=9.0
- MNIST, only 01, PCA-30: MSE=7.3
- MNIST, all-dig, PCA-30: MSE=14.2
- MNIST, only 0, PCA-18: MSE=13.0
- MNIST, only 1, PCA-18: MSE=3.7
- MNIST, only 01, PCA-18: MSE=10.6
- MNIST, all-dig, PCA-18: MSE=20.0
- MNIST, only 0, autoenc-st0b5e10: MSE=50.0 (averages everything) // 5 batches, 10 epochs (default: targ-CE, opt-CG)
- MNIST, only 0, autoenc-stNorm(0,0.3)b5e1000: MSE=12.6 (continues optimizing)
- MNIST, only 0, autoenc-stNorm(0,0.3)Tie-b5e400: MSE=16.0, 2-3 hours // seems no difference from the previous case
- MNIST, only 0, autoenc-stNorm(0,0.3[*2,4])Tie-b5e400: MSE=23.4
- MNIST, only 0, autoenc-stNorm(0,0.2)-b5e100,targ-MSE: MSE=55.0, (continues optimizing, diverse) // slower, but okay
- could not make stochastic gradient find non-trivial optimum
- MNIST, only 0, autoenc-LeCunInitTanh(Last)Mean-b5e300,targCE: MSE=131.8
- MNIST, only 0, autoenc-stLeCunInitx10-b5e300: MSE=28.7
- MNIST, only 0, pretrain-tiedw-1-stNorm(0,0.3)-b6e50: MSE=2.7, 20 min
- MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3)-b6: MSE1(e200): 0.86, MSE2(e500): 3.1, MSE3(e200): 3.3, MSE4(e200): 9.7. Backprop, 300it: MSE=6.5
- MNIST, only 0, pretrain-tiedw-stNorm(0,0.3)-stoch-b150: MSE1(e200): 1.6, MSE2(e500): 4.2, MSE3(e200): 2.3, MSE4(e200): 4.7. Backprop, 500it: MSE=3.0 // 2 hours
- MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3), targ-MSE, arch-sigm+1e-4(except-linear, last): // 630 s
- level1: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=3.2.
- level2: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=7.3.
- level3: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=4.1.
- level4: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=6.0.
- backprop: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=8.0. // 630 s
- MNIST, all-dig, pretrain-tiedw-stNorm(0,0.3), targ-Xentropy, arch-sigm: // 730 s
- level1: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=1.7.
- level2: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=5.3.
- level3: 3ep, momentum=0.97, nbatches=1500, step=(k+1)(-1/4), MSE=2.5.
- level4: 10ep, momentum=0.97, nbatches=1500, step=0.01*(k+1)(-1/4), MSE=7.4.
- backprop: 3ep, momentum=0.97, nbatches=1500, step=0.1*(k+1)(-1/4), MSE=8.7. // 645 s
- MNIST, all-dig, backprop train, stNorm(0,0.3), targ-Xentropy, arch-sigm, 30ep, momentum=0.97, nbatches=1500, step=0.1*(k+1)(-1/4), MSE=8.2, // 6280 s