SZTUCZNA INTELIGENCJA

Transkrypt

SZTUCZNA INTELIGENCJA
POLITECHNIKA RZESZOWSKA
WYDZIAŁ ELEKTROTECHNIKI I INFORMATYKI
KATEDRA INFORMATYKI I AUTOMATYKI
SZTUCZNA INTELIGENCJA
PROJEKT
Temat: Zrealizować sieć neuronową uczoną algorytmem wstecznej propagacji
błędu z przyśpieszeniem metodą momentum (learnbpm) uczącą się identyfikacji
spamu.
Wykonał
Mateusz Drozdowski
II EF-DI
P03
Spis treści.
1. Opis problemu........................................................................................................................................- 3 2. Przygotowanie danych. ..........................................................................................................................- 3 2.1. Atrybuty rekordów zawartych w repozytorium..............................................................................- 3 2.2. Wczytanie danych uczących. ..........................................................................................................- 4 2.3. Normalizacja danych. .....................................................................................................................- 4 3. Opis Algorytmu. ....................................................................................................................................- 5 3.1. Siec neuronowa...............................................................................................................................- 5 3.2. Opis metody ....................................................................................................................................- 6 3.3. Skrypt realizujący sieć neuronową. ................................................................................................- 7 4. Eksperymenty. .......................................................................................................................................- 8 5. Wnioski i podsumowanie.....................................................................................................................- 14 -
-2-
1. Opis problemu.
Celem projektu jest stworzenie sieci neuronowej, która na podstawie informacji dotyczących
wiadomości e-mail rozpoznaje wiadomości i jest w stanie zaklasyfikować je jako zwykłą bądź też
niechciany spam.
E-mail spam - znany także jako "śmieci", niechciane wiadomości, jest podzbiorem spamu, który
dotyczy praktycznie identycznych wiadomości wysłanych do dużej liczby odbiorców za pośrednictwem
poczty elektronicznej. Powszechnym synonimem spamu jest niechciana poczta masowa (ang. UBE).
Definicje spamu zazwyczaj zawierają aspekty, takie jak fakt, że email jest niechciany i wysłany do dużej
liczby odbiorców.
Istnieje także spam z gatunku "UCE", czyli niechciana oferta handlowa, spam o charakterze handlowym
zakazany przez polskie prawo i dyrektywę UE.
Dane użyte przy tworzeniu projektu zostały pobrane z repozytorium należącego do Uniwersytetu
Kalifornijskiego w Irvine (http://archive.ics.uci.edu/ml/datasets/Spambase). Repozytorium zostało
stworzone przez Marka Hopkinsa, Erika Reebera, George'a Formana, Jaapa Suermondta z HewlettPackard Labs.
Analizie poddanych zostało 4601 wiadomości e-mail (każda wiadomość obejmuje jeden wiersz
pliku z danymi). Wśród analizowanych wiadomości znajduje się 1813 wiadomości niechcianych, spamu i
2788 wiadomości zwykłych. Każda wiadomość została opisana 58 atrybutami (jeden atrybut to jedna
kolumna), przy czym ostatnia kolumna mówi czy wiadomość należy do spamu czy nie.
2. Przygotowanie danych.
2.1. Atrybuty rekordów zawartych w repozytorium.
Numer kolumny
Typ danych
Zakres danych
1-48
ciągły rzeczywisty
[ 0 ... 100 ]
49-54
ciągły rzeczywisty
[ 0 ... 100 ]
55
ciągły rzeczywisty
[ 1, ... ]
56
ciągły całkowity
[ 1, ... ]
57
ciągły całkowity
[ 1, ... ]
58
nominalny
{ 0, 1 }
Opis
Procent słów ze słownika w stosunku do
wszystkich słów w wiadomości.
Procent znaków ze zbioru w stosunku do
wszystkich znaków w wiadomości.
Średnia długość nieprzerwanego ciągu
wielkich znaków w danej wiadomości.
Długość najdłuższego nieprzerwanego
ciągu wielkich liter w danej wiadomości.
Całkowita liczba wielkich liter w danej
wiadomości.
Oznaczenie, czy wiadomość jest
spamem.
Słownik
wyrazów:
make, address, all, 3d, our, over, remove, internet, order, mail, receive, will, people,
report, addresses, free, business, email, you, credit, your, font, 000, money, hp, hpl,
george, 650, lab, labs, telnet, 857, data, 415, 85, technology, 1999, parts, pm, direct,
cs, meeting, original, project, re, edu, table, conference
Zbiór znaków:
; ( [ ! $ #
-3-
Przed przygotowaniem danych, w pierwszej kolejności należy odpowiednio dostosować
środowisko pracy. W celu dokonania tego, nasz skrypt powinien zaczynać się w następujący sposób:
clc
clear all
close all
nntwarn off
warning off
%wyczyszczenie okna poleceń
%wyczyszczenie przestrzeni
%zamknięcie aktualnie wyświetlanych wykresów
%wyłączenie ostrzeżeń
2.2. Wczytanie danych uczących.
data = load('spambase.data');
j = 1;
for i=1:XX:length(data(:,1))
temp(j,:) = data(i,:);
j=j+1;
end
clear data
data = temp;
% XX - należy podac, co ktory wiersz ma byc wczytany
Napisany w ten sposób fragment skryptu wczytujący dane z pliku do zmiennej data daje nam
trochę elastyczności, otóż możemy wczytać zarówno cały plik (w miejsce XX wpisać 1), bądź tylko
wybiórcze dane uczące, np. co 5 wiersz.
Po wczytaniu danych otrzymujemy macierz posiadającą 4601 wierszy i 58 kolumn. Pierwsze 57
kolumn zawiera informacje dotyczące wiadomości email, natomiast ostatnia kolumna zawiera informację
czy dana wiadomość jest spamem, czy też nie. Należy oddzielić od siebie te 2 rzeczy. Kolumny 1-57
zostają przy użyciu odpowiedniego skryptu zapisane do wektora wejść P, natomiast ostatnia kolumna
posłuży nam za wektor wyjść T:
for i = 1:(length(data(1,:))-1)
for j = 1:length(data(:,1))
P(j,i) = data(j,i);
end
end
T=data( :,length(data(1,:)) );
2.3. Normalizacja danych.
Wczytane przez nas dane są już odpowiednio posortowane, jednak posiadają bardzo rozbieżne
wartości i sieć nie będzie w stanie przetworzyć ich w odpowiedni sposób oraz nauczyć się. Należy
zastosować normalizację danych, co zwróci nam dane z przedziału [ 0...1 ], a z taką formą sieć poradzi
sobie bez problemu. Normalizacja przeprowadzona jest w następujący sposób: znajdujemy w danej
kolumnie największy element, a następnie wszystkie elementy tej kolumny dzielimy przez znalezione
maksimum. Proces ten realizuje poniższy skrypt:
for i=1:length(P(1,:))
maximum(i) = max(P(:,i));
for j=1:length(P)
P(j,i) = P(j,i)/maximum(i);
end
end
-4-
3. Opis Algorytmu.
3.1. Siec neuronowa.
Sieć neuronowa (sztuczna sieć neuronowa) to ogólna nazwa struktur matematycznych i ich
programowych lub sprzętowych modeli, realizujących obliczenia lub przetwarzanie sygnałów poprzez
rzędy elementów, zwanych sztucznymi neuronami, wykonujących pewną podstawową operację na swoim
wejściu. Oryginalną inspiracją takiej struktury była budowa naturalnych neuronów oraz układów
nerwowych, w szczególności mózgu.
Sztuczna sieć neuronowa jest modelem matematycznym, składającym się z sieci węzłów
obliczeniowych zwanych neuronami i ich połączeń. Model ten ma za zadanie symulować pracę neuronów
w ludzkim mózgu, jednak istnieją znaczne różnice w ich działaniu.
Z punktu widzenia matematycznego, dobrze skonstruowana sieć neuronowa jest w stanie "nauczyć
się" aproksymować dowolną funkcję wielu zmiennych. W wyniku aproksymacji sieć jest w stanie
uogólnić nabytą wiedzę na nieznane jej, choć podobne problemy. Zdolność ta nazywa się generalizacją.
Dane wejściowe zostają pomnożone w neuronie przez odpowiednio przypisane wagi, a następnie
sumowane i przekazywane na wyjście.
Rys. 1 - model neuronu.
x = [x1, x2, ..., xi, ..., xn]T - wektor sygnałów wejściowych
w = [w1, w2, ..., wi, ..., wn]T - wektor wag
y - sygnał wyjściowy
(
)
 N

Sygnał wyjściowy neuronu wyraża się wzorem y = f  ∑ wi xi  = f wT x , gdzie f to odpowiednia
 i =0

funkcja aktywacji.
-5-
W projekcie wykorzystana jest trójwarstwowa sieć neuronowa, której model przedstawiony jest
poniżej:
3.2. Opis metody
Algorytmem uczenia sieci neuronowej w tym projekcie jest uczenie pod nadzorem metodą
wstecznej propagacji błędu z przyspieszeniem metodą momentum (learnbpm).
Zgodnie z tym algorytmem, wektor błędu sieci obliczany dla warstwy wyjściowej rzutowany
zostaje wstecz poprzez kolejne jej warstwy. Zabieg ten umożliwia obliczenie nowych wartości
współczynników wagowych poszczególnych warstw, a w efekcie zmniejszenie średniokwadratowego
błędu sieci (SSE).
W pierwszej kolejności wyliczany jest błąd ostatniej warstwy, w oparciu o sygnał wzorcowy i
wyjściowy. W pozostałych warstwach błąd obliczany jest jako ustalona funkcja błędu neuronów warstwy
poprzedzającej. Algorytm ten należy do gradientowych metod optymalizacji, gdyż opiera się o
stwierdzenie, że gradient funkcji wskazuje kierunek jej najszybszego wzrostu, a zmieniając jego znak na
przeciwny, uzyskujemy kierunek najszybszego spadku funkcji. Możemy w ten sposób minimalizować
funkcję celu przez modyfikację współczynników wagowych w kierunku najszybszego spadku funkcji.
Zmiana wartości współczynników wagowych i progowych dla i-tego wejścia i i-tego neuronu
opisana jest zależnością:
?W(i,j) = mc * ?Wp(i,j) + (l - mc) * lr * d(i) * p(j)
?B(i) = mc * ?Bp(i) + (l - mc) * lr * d(i)
Stała momentum (parametr mc) określa wpływ poprzedniej zmiany wag ?Wp i współczynników
progowych ?Bp na zmianę dokonywaną obecnie. Zastosowanie metody momentum przyczynia się do
likwidacji zbyt gwałtownych zmian wartości funkcji błędu sieci. Umożliwia to bezpieczne zwiększenie
wartości współczynnika prędkości uczenia lr.
-6-
Wykorzystując oprogramowani firmy MathWorks opisaną metodę wywołuje się w następujący
sposób:
[dW, dB] = learnbpm (P,D,LR,MC,dW,dB)
Gdzie odpowiednio:
P - macierz wektorów wejściowych (wymiar R*Q, R - liczba wejść warstwy, Q - ilość wektorów),
D - macierz pochodnych błędów warstwy (wymiar S*Q, S - liczba neuronów w warstwie),
LR - współczynnik uczenia sieci,
MC - wartość stałej momentum,
dW - macierz przyrostów współczynników warstwy w poprzednim kroku (wymiar S*R),
dB - wektor przyrostów współczynników progowych warstwy w poprzednim kroku (wymiar S*1).
Wartości zwracane przez metodę:
dW - nowa macierz przyrostów współczynników wagowych warstwy (wymiar S*R),
dB - nowa macierz przyrostów współczynników progowych warstwy (wymiar S*1).
3.3. Skrypt realizujący sieć neuronową.
T = T';
P = P';
%transponowanie macierzy T
%transponowanie macierzy P
[R,Q] = size(P); %ustawienie rozmiarów wejścia, R liczba wierszy, Q liczba kolumn
[S3,Q] = size(T); %ustawienie rozmiarów wyjścia,
%S3 liczba wierszy macierzy wejścia, Q liczba kolumn
S1=10; %ustawienie liczby neuronów w warstwie S1
S2=7;
%ustawienie liczby neuronów w warstwie S2
lr=0.01; %współczynnik uczenia
mc=0.9; %stała momentum
err_goal=0.1; %docelowy błąd
%zainicjalizowanie neuronów i ich współczynników wagowych (1)
[W1,B1] = nwtan(S1,R);
[W2,B2] = nwtan(S2,S1);
[W3,B3] = rands(S3,S2);
%stworzenie tablic wypełnionych zerami
dW1=zeros(size(W1));
dW2=zeros(size(W2));
dW3=zeros(size(W3));
dB1=zeros(size(B1));
dB2=zeros(size(B2));
dB3=zeros(size(B3));
disp_freq=100;
%częstotliwość wyświetlania wyników
max_epoch=30000; %liczba kroków uczenia
error=[]; %wektor zawierający błędy kolejnych kroków uczenia
A1 = tansig(W1*P,B1);
%obliczenie wyjscia dla sieci, z funkcją aktywacji tansig
A2 = tansig(W2*A1,B2);
A3 = purelin(W3*A2,B3); %obliczenie wyjscia dla sieci, W1*P+B1
%z funkcją aktywacji purelin
E = T-A3;
%oblicznie błędu pomiędzy wzorcem a wyjściem z sieci
SSE = sumsqr(E); %oblicznie funkcji celu, czyli sumy z kwadratów błędów
-7-
%pętla wykonująca algorytm uczenia sieci dla podanej liczby kroków uczenia
for epoch=1:max_epoch,
% zakończenie gdy funkcja celu jest mniejsza od docelowego błędu
if SSE < err_goal, epoch=epoch-1; break; end,
%obliczenie wektorów błędów warstw wyjściowych
D3 = deltalin(A3,E);
D2 = deltatan(A2,D3,W3);
D1 = deltatan(A1,D2,W2);
%obliczenie
[dW1,dB1] =
[dW2,dB2] =
[dW3,dB3] =
zmian wag przy uczeniu algorytmem wstecznej propagacji z momentum
learnbpm(P,D1,lr,mc,dW1,dB1);
learnbpm(A1,D2,lr,mc,dW2,dB2);
learnbpm(A2,D3,lr,mc,dW3,dB3);
%aktualizacja wag
W1 = W1 + dW1; B1 = B1 + dB1;
W2 = W2 + dW2; B2 = B2 + dB2;
W3 = W3 + dW3; B3 = B3 + dB3;
%obliczenie wyjscia z sieci dla nowych wag
A1 = tansig(W1*P,B1);
A2 = tansig(W2*A1,B2);
A3 = purelin(W3*A2,B3);
E = T-A3;
SSE = sumsqr(E); %tworzenie funkcji celu, zapisywanie do wektora error jego
%aktualnej wartości i nowej wartosci funkcji celu
error = [error SSE];
%wyświetlanie wykresu i informacji o przebiegu uczenia
if (rem(epoch,disp_freq) == 0)
info = sprintf('Epoch: %g/%g, Err_goal: %g, SSE: %g, ANS: %g
\n',epoch,max_epoch,err_goal,SSE, 100*(1-sum((abs(T-A3)>.5)')/length(T)));
fprintf(info,0);
plot(1:length(T),T,'r',1:length(T),A3,'g');
legend('Rzeczywiste','Wyuczone',1);
pause(1e-100);
end
end
(1) - generowanie macierzy wag i wektora biasu (przesunięcia) przy użyciu metody Nguyen-Widrow do inicjalizacji ich
wartości dla warstwy tan-sigmoid - [W1,B1] = nwtan(S1,R). Stworzona zostaje macierz o wymiarach S1 × R i wektor
B1 o wymiarze S1.
[W3,B3] = rands(S3,S2) - generowanie macierzy wag i wektora biasu o wartościach statycznych o jednorodnym
rozkładzie z zakresu [-1, 1]. Stworzona zostaje macierz W3 o wymiarach S3 × S2 i wektor B3 o wymiarze S3.
4. Eksperymenty.
Eksperymenty wykonywane na gotowym skrypcie sieci neuronowej w głównej mierze opierały się
na modyfikowaniu ilości neuronów w warstwie pierwszej i drugiej, a także współczynnika prędkości
uczenia i stałej momentum, na podstawie wyników otrzymanych przy każdej z prób.
Wczytując dane uczące z repozytorium otrzymujemy ogromną ilość informacji do przetworzenia.
Wektor wejściowy zawiera macierz o wymiarach 4601 × 57, co daje nam 262257 danych.
-8-
Ustalono początkowe parametry sieci na poziomie:
S1
S2
lr
mc
=
=
=
=
25;
10;
0.01;
0.9;
W efekcie otrzymano wynik:
Epoch: 100/100000, Err_goal: 0.1, SSE: NaN, ANS: 100
Epoch: 200/100000, Err_goal: 0.1, SSE: NaN, ANS: 100
Epoch: 300/100000, Err_goal: 0.1, SSE: NaN, ANS: 100
Funkcja celu (SSE) już podczas uruchomienia skryptu okazała się mieć bardzo dużą wartość, która nie
malała więc zmniejszony został współczynnik uczenia.
lr = 0.001;
Wynik:
Epoch: 100/100000, Err_goal: 0.1, SSE: 1.46983e+091, ANS: 0
Epoch: 200/100000, Err_goal: 0.1, SSE: 9.44763e+181, ANS: 0
Epoch: 300/100000, Err_goal: 0.1, SSE: 6.07266e+272, ANS: 0
Wynik SSE w dalszym ciągu wzrasta, a celem sieci jest jego zmniejszenie do ustalonego celu. W takim
wypadku zostaje zwiększony współczynnik stałej momentum.
mc = 0.99;
Epoch: 13000/100000, Err_goal: 0.1, SSE: 147.919, ANS: 96.1965
Epoch: 14000/100000, Err_goal: 0.1, SSE: 143.455, ANS: 96.2834
Epoch: 15000/100000, Err_goal: 0.1, SSE: 139.182, ANS: 96.5008
-9-
Sieć neuronowa w końcu zaczęła się uczyć, jednak proces ten przebiegał strasznie wolno. Zmieniona
zostaje ilość neuronów w obydwu warstwach.
S1=100;
S2=25;
lr=0.001;
mc=0.99;
Epoch: 8000/100000, Err_goal: 0.1, SSE: 158.023, ANS: 95.9139
Epoch: 9000/100000, Err_goal: 0.1, SSE: 151.108, ANS: 96.0661
Epoch: 10000/100000, Err_goal: 0.1, SSE: 145.336, ANS: 96.2182
Zmieniając ilość neuronów w warstwach sieć w dalszym ciągu uczy się strasznie wolno. Dodatkowo ilość
przetwarzanych informacji obciąża strasznie pamięć i procesor. W rezultacie prędkość przejść sieci
podczas uczenia się wynosi średnio 2000 przejść / 1 min. W celu dokładniejszego i szybszego
przetestowania sieci zbiór danych zostaje zredukowany do 460 rekordów.
Na tak przygotowanym zbiorze danych przeprowadzono dalsze eksperymenty.
Ustawienia początkowe sieci:
S1=10;
S2=5;
lr=0.1;
mc=0.9;
Epoch: 100/100000, Err_goal: 0.1, SSE: 1.07609e+283, ANS: 0
Epoch: 200/100000, Err_goal: 0.1, SSE: NaN, ANS: 100
Epoch: 300/100000, Err_goal: 0.1, SSE: NaN, ANS: 100
- 10 -
Funkcja celu wzrasta więc jak we wcześniejszym eksperymencie zmniejszony zostaje współczynnik
uczenia:
lr=0.01;
Epoch: 100/100000, Err_goal: 0.1, SSE: 109.782, ANS: 60.6522
Epoch: 200/100000, Err_goal: 0.1, SSE: 109.78, ANS: 60.6522
Epoch: 300/100000, Err_goal: 0.1, SSE: 109.78, ANS: 60.6522
SSE pozostaje cały czas na niezmienionym poziomie. Postanowiono zarówno zwiększyć liczbę neuronów
jak i jeszcze pomniejszyć współczynnik uczenia:
S1=25;
S2=10;
lr=0.001;
mc=0.9;
Epoch: 10000/100000, Err_goal: 0.1, SSE: 11.069, ANS: 97.8261
Epoch: 20000/100000, Err_goal: 0.1, SSE: 6.11325, ANS: 98.6957
Epoch: 30000/100000, Err_goal: 0.1, SSE: 5.08459, ANS: 98.913
W wyniku tego eksperymentu zauważyć można postęp w uczeniu się sieci. Aby osiągnąć zamierzony cel
liczba neuronów zostaje lekko zredukowana, a współczynnik uczenia zwiększony w celu przyspieszenia
procesu:
S1=10;
S2=7;
lr=0.01;
mc=0.9;
- 11 -
W taki sposób dobrane dane pozwalają na nauczenie się sieci z założoną wielkością błędu uczenia na
poziomie 0.1
Epoch:
Epoch:
Epoch:
Epoch:
43000/100000,
44000/100000,
45000/100000,
45281/100000,
Err_goal:
Err_goal:
Err_goal:
Err_goal:
0.1,
0.1,
0.1,
0.1,
SSE:
SSE:
SSE:
SSE:
0.2265,
0.1091,
0.1013,
0.0999,
ANS:
ANS:
ANS:
ANS:
100
100
100
100
Chcąc sprawdzić zachowanie się sieci neuronowej dla jeszcze mniejszego zbioru danych wejściowych
ograniczono dane do około 300 rekordów.
Lekko zmieniając parametry nauczonej w powyższym eksperymencie sieci otrzymane zostały
zadowalające wyniki:
S1=11;
S2=7;
lr=0.01;
mc=0.9;
Epoch:
Epoch:
Epoch:
Epoch:
6300/30000,
6400/30000,
6500/30000,
6527/30000,
Err_goal:
Err_goal:
Err_goal:
Err_goal:
0.1,
0.1,
0.1,
0.1,
SSE:
SSE:
SSE:
SSE:
0.1213,
0.1070,
0.1377,
0.0969,
- 12 -
ANS:
ANS:
ANS:
ANS:
100
100
100
100
Epoch:
Epoch:
Epoch:
Epoch:
21800/30000,
21900/30000,
22000/30000,
22097/30000,
Err_goal:
Err_goal:
Err_goal:
Err_goal:
0.01,
0.01,
0.01,
0.01,
SSE:
SSE:
SSE:
SSE:
0.0101851, ANS: 100
0.0101219, ANS: 100
0.0100596, ANS: 100
0.0100, ANS: 100
- 13 -
5. Wnioski i podsumowanie.
Celem projektu było zapoznanie się ze strukturą wielowarstwowych sztucznych sieci
neuronowych. Zagadnienie to zostało opracowane na przykładzie skryptu realizującego sieć neuronową
uczoną algorytmem wstecznej propagacji błędu z przyspieszeniem metodą momentum (learnbpm)
rozpoznającą wiadomości spam. Dane uczące wykorzystane w projekcie zostały pobrane ze strony
Uniwersytetu Kalifornijskiego w Irvine (adres na str. 3).
Przed rozpoczęciem realizacji zagadnienia środowisko MATLAB zostało odpowiednio
przygotowane, a dane znormalizowane, ponieważ zawierały wartości z bardzo szerokiego zakresu
zarówno liczb całkowitych jak i rzeczywistych.
Realizując projekt z przyczyn technicznych zbiór danych uczących musiał zostać pomniejszony.
Mimo dość dużej mocy obliczeniowej jedno przejście uczenia sieci trwały na tyle długo, by spowodować,
że czas jednego eksperymentu był na poziomie kilku godzin. Na odpowiednio ograniczonym zbiorze
danych uczących eksperymenty przebiegały znacznie szybciej, co pozwoliło na dobranie odpowiednich
parametrów. Niestety wykorzystując metodę learnbpm nie ustalona została żadna zależność między
parametrami sieci, a efektem końcowym. Zauważony został fakt, że nawet niewielkie zmniejszenie zbioru
uczącego powoduje ponowny wymóg dostrojenia parametrów sieci w celu poprawnego nauczenia.
Przeprowadzane eksperymenty mimo ograniczenia zbioru sprowadzały się do metody "prób i
błędów". Manipulowano parametrami sieci przy jednoczesnej obserwacji zachowania się jej. Zmianie
ulegała liczba neuronów w warstwach S1 i S2, współczynnik uczenia i stała momentum. Zmieniane były
także dane uczące na wejściu sieci w celu wyeliminowania potencjalnie zbędnych rekordów. Ostatecznie
udało się dobrać parametry sieci w taki sposób, aby osiągnąć zamierzony błąd na poziomie 0,1, a nawet
przy ograniczonym zbiorze do 300 rekordów na poziomie 0,01, przy 100% nauczeniu sieci.
Wraz z rozwojem technologii sieci neuronowe bezproblemowo mogą być wprowadzane w coraz
szerszym zakresie dziedzin nauki i techniki. Odpowiednio zaprojektowana sieć mogłaby stanowić bardzo
dobry filtr antyspamowy, który mógłby dokładnie filtrować niepożądane wiadomości mimo braku
bezpośredniej zależności pomiędzy zwykłą wiadomością. Jedynym wymogiem jest dobranie
odpowiedniej sieci neuronowej oraz nauczenie jej przy pomocy dość dużego zbioru danych uczących.
- 14 -

Podobne dokumenty