Theano - przykład szkolenia trywialnego
Theano jest bardzo przydatne w uczeniu sieci neuronowych, gdzie musimy wielokrotnie obliczać koszt i gradienty, aby osiągnąć optimum. W przypadku dużych zbiorów danych wymaga to intensywnych obliczeń. Theano robi to skutecznie dzięki wewnętrznej optymalizacji grafu obliczeniowego, który widzieliśmy wcześniej.
Stwierdzenie problemu
Teraz nauczymy się, jak używać biblioteki Theano do trenowania sieci. Weźmiemy prosty przypadek, w którym zaczniemy od zestawu danych czterech funkcji. Sumę tych cech obliczamy po zastosowaniu określonej wagi (ważności) do każdej cechy.
Celem szkolenia jest taka modyfikacja wag przypisanych każdej funkcji, aby suma osiągnęła docelową wartość 100.
sum = f1 * w1 + f2 * w2 + f3 * w3 + f4 * w4
Gdzie f1, f2, ... to wartości funkcji i w1, w2, ... są ciężarkami.
Pozwólcie, że kwantyfikuję przykład, aby lepiej zrozumieć stwierdzenie problemu. Przyjmiemy początkową wartość 1,0 dla każdej cechy i weźmiemy w1 równa się0.1, w2 równa się 0.25, w3 równa się 0.15, i w4 równa się 0.3. Nie ma określonej logiki w przypisywaniu wartości wag, to tylko nasza intuicja. Zatem początkowa suma jest następująca -
sum = 1.0 * 0.1 + 1.0 * 0.25 + 1.0 * 0.15 + 1.0 * 0.3
Jakie sumy 0.8. Teraz będziemy nadal modyfikować przypisanie wagi, tak aby suma zbliżała się do 100. Bieżąca wartość wynikowa0.8 jest daleko od naszej pożądanej wartości docelowej 100. W terminach uczenia maszynowego definiujemy costjako różnica między wartością docelową a bieżącą wartością wyjściową, zwykle podniesiona do kwadratu, aby zwiększyć błąd. Zmniejszamy ten koszt w każdej iteracji, obliczając gradienty i aktualizując nasz wektor wag.
Zobaczmy, jak ta cała logika jest implementowana w Theano.
Deklarowanie zmiennych
Najpierw deklarujemy nasz wektor wejściowy x w następujący sposób -
x = tensor.fvector('x')
Gdzie x jest jednowymiarową tablicą wartości zmiennoprzecinkowych.
Definiujemy skalar target zmienna, jak podano poniżej -
target = tensor.fscalar('target')
Następnie tworzymy tensor odważników W z wartościami początkowymi, jak omówiono powyżej -
W = theano.shared(numpy.asarray([0.1, 0.25, 0.15, 0.3]), 'W')
Definiowanie wyrażenia Theano
Teraz obliczamy wynik za pomocą następującego wyrażenia -
y = (x * W).sum()
Zauważ, że w powyższym oświadczeniu x i Wsą wektorami, a nie prostymi zmiennymi skalarnymi. Teraz obliczamy błąd (koszt) za pomocą następującego wyrażenia -
cost = tensor.sqr(target - y)
Koszt to różnica między wartością docelową a bieżącą wydajnością, do kwadratu.
Aby obliczyć gradient, który mówi nam, jak daleko jesteśmy od celu, używamy wbudowanego grad metoda w następujący sposób -
gradients = tensor.grad(cost, [W])
Aktualizujemy teraz weights wektor, przyjmując współczynnik uczenia się równy 0.1 w następujący sposób -
W_updated = W - (0.1 * gradients[0])
Następnie musimy zaktualizować nasz wektor wag przy użyciu powyższych wartości. Robimy to w następującym oświadczeniu -
updates = [(W, W_updated)]
Definiowanie / wywoływanie funkcji Theano
Na koniec definiujemy plik function w Theano, aby obliczyć sumę.
f = function([x, target], y, updates=updates)
Aby wywołać powyższą funkcję określoną liczbę razy, tworzymy plik for pętla w następujący sposób -
for i in range(10):
output = f([1.0, 1.0, 1.0, 1.0], 100.0)
Jak wspomniano wcześniej, wejściem do funkcji jest wektor zawierający początkowe wartości dla czterech cech - przypisujemy wartość 1.0do każdej funkcji bez konkretnego powodu. Możesz przypisać różne wybrane wartości i sprawdzić, czy funkcja ostatecznie jest zbieżna. W każdej iteracji wydrukujemy wartości wektora wagi i odpowiadające mu dane wyjściowe. Pokazuje to poniższy kod -
print ("iteration: ", i)
print ("Modified Weights: ", W.get_value())
print ("Output: ", output)
Pełna lista programów
Pełną listę programów przedstawiono tutaj w celach informacyjnych -
from theano import *
import numpy
x = tensor.fvector('x')
target = tensor.fscalar('target')
W = theano.shared(numpy.asarray([0.1, 0.25, 0.15, 0.3]), 'W')
print ("Weights: ", W.get_value())
y = (x * W).sum()
cost = tensor.sqr(target - y)
gradients = tensor.grad(cost, [W])
W_updated = W - (0.1 * gradients[0])
updates = [(W, W_updated)]
f = function([x, target], y, updates=updates)
for i in range(10):
output = f([1.0, 1.0, 1.0, 1.0], 100.0)
print ("iteration: ", i)
print ("Modified Weights: ", W.get_value())
print ("Output: ", output)
Po uruchomieniu programu zobaczysz następujące dane wyjściowe -
Weights: [0.1 0.25 0.15 0.3 ]
iteration: 0
Modified Weights: [19.94 20.09 19.99 20.14]
Output: 0.8
iteration: 1
Modified Weights: [23.908 24.058 23.958 24.108]
Output: 80.16000000000001
iteration: 2
Modified Weights: [24.7016 24.8516 24.7516 24.9016]
Output: 96.03200000000001
iteration: 3
Modified Weights: [24.86032 25.01032 24.91032 25.06032]
Output: 99.2064
iteration: 4
Modified Weights: [24.892064 25.042064 24.942064 25.092064]
Output: 99.84128
iteration: 5
Modified Weights: [24.8984128 25.0484128 24.9484128 25.0984128]
Output: 99.968256
iteration: 6
Modified Weights: [24.89968256 25.04968256 24.94968256 25.09968256]
Output: 99.9936512
iteration: 7
Modified Weights: [24.89993651 25.04993651 24.94993651 25.09993651]
Output: 99.99873024
iteration: 8
Modified Weights: [24.8999873 25.0499873 24.9499873 25.0999873]
Output: 99.99974604799999
iteration: 9
Modified Weights: [24.89999746 25.04999746 24.94999746 25.09999746]
Output: 99.99994920960002
Zauważ, że po czterech iteracjach dane wyjściowe to 99.96 i po pięciu iteracjach jest 99.99, który jest bliski naszej pożądanej wartości docelowej 100.0.
W zależności od pożądanej dokładności, możesz bezpiecznie stwierdzić, że sieć jest szkolona w 4 do 5 iteracjach. Po zakończeniu treningu odszukaj wektor wag, który po 5 iteracjach przyjmuje następujące wartości -
iteration: 5
Modified Weights: [24.8984128 25.0484128 24.9484128 25.0984128]
Możesz teraz użyć tych wartości w swojej sieci do wdrożenia modelu.