Udostępnij za pośrednictwem


Przewodnik po języku specyfikacji sieci neuronowej net# dla usługi Machine Learning Studio (wersja klasyczna)

DOTYCZY: Dotyczy.Machine Learning Studio (wersja klasyczna) Nie dotyczy.Azure Machine Learning

Ważne

Obsługa programu Machine Learning Studio (wersja klasyczna) zakończy się 31 sierpnia 2024 r. Zalecamy przejście do usługi Azure Machine Learning przed tym terminem.

Od 1 grudnia 2021 r. nie będzie można tworzyć nowych zasobów programu Machine Learning Studio (wersja klasyczna). Do 31 sierpnia 2024 r. można będzie nadal korzystać z istniejących zasobów programu Machine Learning Studio (wersja klasyczna).

Dokumentacja programu ML Studio (wersja klasyczna) jest wycofywana i może nie być aktualizowana w przyszłości.

Net# to język opracowany przez firmę Microsoft, który służy do definiowania złożonych architektur sieci neuronowych, takich jak głębokie sieci neuronowe lub konwolucje dowolnych wymiarów. Możesz użyć złożonych struktur, aby ulepszyć uczenie się danych, takich jak obraz, wideo lub dźwięk.

Specyfikację architektury net# można używać we wszystkich modułach sieci neuronowych w usłudze Machine Learning Studio (wersja klasyczna):

W tym artykule opisano podstawowe pojęcia i składnię wymaganą do opracowania niestandardowej sieci neuronowej przy użyciu platformy Net#:

  • Wymagania dotyczące sieci neuronowej i sposób definiowania podstawowych składników
  • Składnia i słowa kluczowe języka specyfikacji Net#
  • Przykłady niestandardowych sieci neuronowych utworzonych przy użyciu sieci Net#

Podstawy sieci neuronowej

Struktura sieci neuronowej składa się z węzłów zorganizowanych w warstwach i ważonych połączeń (lub krawędzi) między węzłami. Połączenia są kierunkowe, a każde połączenie ma węzeł źródłowy i węzeł docelowy.

Każda szkolna warstwa (ukryta lub wyjściowa) ma co najmniej jeden pakiet połączeń. Pakiet połączenia składa się z warstwy źródłowej i specyfikacji połączeń z tej warstwy źródłowej. Wszystkie połączenia w danym pakiecie współużytkuje warstwę źródłową i docelową. W środowisku Net#pakiet połączenia jest uznawany za należący do warstwy docelowej pakietu.

Platforma Net# obsługuje różne rodzaje pakietów połączeń, które umożliwiają dostosowanie sposobu mapowania danych wejściowych na ukryte warstwy i mapowane na dane wyjściowe.

Domyślny lub standardowy pakiet jest pełnym pakietem, w którym każdy węzeł w warstwie źródłowej jest połączony z każdym węzłem w warstwie docelowej.

Ponadto platforma Net# obsługuje następujące cztery rodzaje zaawansowanych pakietów połączeń:

  • Przefiltrowane pakiety. Predykat można zdefiniować przy użyciu lokalizacji węzła warstwy źródłowej i docelowego węzła warstwy. Węzły są połączone za każdym razem, gdy predykat ma wartość True.

  • Pakiety splotowe. W warstwie źródłowej można zdefiniować małe dzielnice węzłów. Każdy węzeł w warstwie docelowej jest połączony z jedną dzielnicą węzłów w warstwie źródłowej.

  • Pakiety puli i pakiety normalizacji odpowiedzi. Są one podobne do pakietów splotowych, w których użytkownik definiuje małe dzielnice węzłów w warstwie źródłowej. Różnica polega na tym, że wagi krawędzi w tych pakietach nie są trenowane. Zamiast tego do wartości węzła źródłowego jest stosowana wstępnie zdefiniowana funkcja w celu określenia wartości węzła docelowego.

Obsługiwane dostosowania

Architektura modeli sieci neuronowych tworzonych w usłudze Machine Learning Studio (wersja klasyczna) może być szeroko dostosowywana przy użyciu platformy Net#. Masz następujące możliwości:

  • Utwórz ukryte warstwy i steruj liczbą węzłów w każdej warstwie.
  • Określ sposób łączenia warstw ze sobą.
  • Zdefiniuj specjalne struktury łączności, takie jak sploty i pakiety udostępniania wagi.
  • Określ różne funkcje aktywacji.

Aby uzyskać szczegółowe informacje o składni języka specyfikacji, zobacz Specyfikacja struktury.

Przykłady definiowania sieci neuronowych dla niektórych typowych zadań uczenia maszynowego można znaleźć w temacie Przykłady.

Wymagania ogólne

  • Musi istnieć dokładnie jedna warstwa wyjściowa, co najmniej jedna warstwa wejściowa i zero lub więcej ukrytych warstw.
  • Każda warstwa ma stałą liczbę węzłów, koncepcyjnie rozmieszczoną w prostokątnej tablicy dowolnych wymiarów.
  • Warstwy wejściowe nie mają skojarzonych wytrenowanych parametrów i reprezentują punkt, w którym dane wystąpienia wchodzą do sieci.
  • Warstwy trenowania (warstwy ukryte i wyjściowe) mają skojarzone wytrenowane parametry, znane jako wagi i uprzedzenia.
  • Węzły źródłowe i docelowe muszą znajdować się w oddzielnych warstwach.
  • Połączenia muszą być acykliczne; innymi słowy, nie może istnieć łańcuch połączeń prowadzących z powrotem do początkowego węzła źródłowego.
  • Warstwa wyjściowa nie może być warstwą źródłową pakietu połączenia.

Specyfikacje struktury

Specyfikacja struktury sieci neuronowej składa się z trzech sekcji: stałej deklaracji, deklaracji warstwy, deklaracji połączenia. Istnieje również opcjonalna sekcja deklaracji udziału. Sekcje można określić w dowolnej kolejności.

Deklaracja stałej

Stała deklaracja jest opcjonalna. Zapewnia ona metodę definiowania wartości używanych gdzie indziej w definicji sieci neuronowej. Instrukcja deklaracji składa się z identyfikatora, po którym następuje znak równości i wyrażenie wartości.

Na przykład następująca instrukcja definiuje stałą x:

Const X = 28;

Aby zdefiniować dwie lub więcej stałych jednocześnie, należy ująć nazwy identyfikatorów i wartości w nawiasach klamrowych i oddzielić je średnikami. Na przykład:

Const { X = 28; Y = 4; }

Prawa strona każdego wyrażenia przypisania może być liczbą całkowitą, liczbą rzeczywistą, wartością logiczną (prawda lub fałsz) lub wyrażeniem matematycznym. Na przykład:

Const { X = 17 * 2; Y = true; }

Deklaracja warstwy

Wymagana jest deklaracja warstwy. Definiuje rozmiar i źródło warstwy, w tym jej pakiety połączeń i atrybuty. Instrukcja deklaracji rozpoczyna się od nazwy warstwy (danych wejściowych, ukrytych lub wyjściowych), a następnie wymiarów warstwy (krotki dodatnich liczb całkowitych). Na przykład:

input Data auto;
hidden Hidden[5,20] from Data all;
output Result[2] from Hidden all;
  • Produktem wymiarów jest liczba węzłów w warstwie. W tym przykładzie istnieją dwa wymiary [520], co oznacza, że w warstwie znajduje się 100 węzłów.
  • Warstwy można zadeklarować w dowolnej kolejności, z jednym wyjątkiem: jeśli zdefiniowano więcej niż jedną warstwę wejściową, kolejność, w jakiej są zadeklarowane, musi odpowiadać kolejności funkcji w danych wejściowych.

Aby określić, że liczba węzłów w warstwie jest określana automatycznie, użyj słowa kluczowego auto . Słowo auto kluczowe ma różny wpływ w zależności od warstwy:

  • W deklaracji warstwy wejściowej liczba węzłów jest liczbą funkcji w danych wejściowych.
  • W ukrytej deklaracji warstwy liczba węzłów jest liczbą określoną przez wartość parametru liczba ukrytych węzłów.
  • W deklaracji warstwy wyjściowej liczba węzłów wynosi 2 dla klasyfikacji dwuklasowej, 1 dla regresji i równej liczbie węzłów wyjściowych dla klasyfikacji wieloklasowej.

Na przykład następująca definicja sieci umożliwia automatyczne określenie rozmiaru wszystkich warstw:

input Data auto;
hidden Hidden auto from Data all;
output Result auto from Hidden all;

Deklaracja warstwy dla warstwy trenowanej (warstwy ukryte lub wyjściowe) może opcjonalnie zawierać funkcję wyjściową (nazywaną również funkcją aktywacji), która domyślnie jest sigmoid dla modeli klasyfikacji i liniowa dla modeli regresji. Nawet jeśli używasz wartości domyślnej, możesz jawnie określić funkcję aktywacji, jeśli jest to wymagane w celu uzyskania jasności.

Obsługiwane są następujące funkcje wyjściowe:

  • Sigmoid
  • liniowy
  • softmax
  • rlinear
  • kwadratowy
  • Sqrt
  • srlinear
  • Abs
  • Tanh
  • brlinear

Na przykład następująca deklaracja używa funkcji softmax :

output Result [100] softmax from Hidden all;

Deklaracja połączenia

Natychmiast po zdefiniowaniu warstwy do trenowania należy zadeklarować połączenia między zdefiniowanymi warstwami. Deklaracja pakietu połączenia rozpoczyna się od słowa kluczowego from, a następnie nazwy warstwy źródłowej pakietu i rodzaju pakietu połączenia do utworzenia.

Obecnie obsługiwane są pięć rodzajów pakietów połączeń:

  • Pełne pakiety wskazywane przez słowo kluczowe all
  • Przefiltrowane pakiety, wskazywane przez słowo kluczowe where, a następnie wyrażenie predykatu
  • Pakiety splotowe, wskazywane przez słowo kluczowe convolve, a następnie atrybuty splotu
  • Pakiety buforowania wskazywane przez słowa kluczowe maksymalna pula lub średnią pulę
  • Pakiety normalizacji odpowiedzi wskazywane przez normę odpowiedzi słowa kluczowego

Pełne pakiety

Pełny pakiet połączenia obejmuje połączenie z każdego węzła w warstwie źródłowej do każdego węzła w warstwie docelowej. Jest to domyślny typ połączenia sieciowego.

Przefiltrowane pakiety

Filtrowana specyfikacja pakietu połączeń zawiera predykat, wyrażony składniowo, podobnie jak wyrażenie lambda języka C#. W poniższym przykładzie zdefiniowano dwa przefiltrowane pakiety:

input Pixels [10, 20];
hidden ByRow[10, 12] from Pixels where (s,d) => s[0] == d[0];
hidden ByCol[5, 20] from Pixels where (s,d) => abs(s[1] - d[1]) <= 1;
  • W predykacie dla ByRowparametru s jest parametr reprezentujący indeks w prostokątnej tablicy węzłów warstwy Pixelswejściowej , i d jest parametrem reprezentującym indeks w tablicy węzłów ukrytej warstwy ByRow. Typ i s d jest krotką liczb całkowitych o długości dwóch. Koncepcyjnie s zakresy dla wszystkich par liczb całkowitych z elementami 0 <= s[0] < 10 i 0 <= s[1] < 20i i d obejmują wszystkie pary liczb całkowitych z wartościami 0 <= d[0] < 10 i 0 <= d[1] < 12.

  • Po prawej stronie wyrażenia predykatu znajduje się warunek. W tym przykładzie dla każdej wartości i d tak, że warunek ma wartość s True, istnieje krawędź z węzła warstwy źródłowej do węzła warstwy docelowej. W związku z tym to wyrażenie filtru wskazuje, że pakiet zawiera połączenie z węzła zdefiniowanego przez s do węzła zdefiniowanego przez d we wszystkich przypadkach, w których s[0] jest równe d[0].

Opcjonalnie można określić zestaw wag dla filtrowanego pakietu. Wartość atrybutu Wagi musi być krotką wartości zmiennoprzecinkowych o długości odpowiadającej liczbie połączeń zdefiniowanych przez pakiet. Domyślnie wagi są generowane losowo.

Wartości wagi są grupowane według indeksu węzła docelowego. Oznacza to, że jeśli pierwszy węzeł docelowy jest połączony z węzłami źródłowymi K, pierwsze K elementy krotki Wagi są wagami pierwszego węzła docelowego w kolejności indeksu źródłowego. To samo dotyczy pozostałych węzłów docelowych.

Można określić wagi bezpośrednio jako stałe wartości. Jeśli na przykład znasz wcześniej wagi, możesz określić je jako stałe przy użyciu tej składni:

const Weights_1 = [0.0188045055, 0.130500451, ...]

Pakiety splotowe

Gdy dane szkoleniowe mają homogeniczną strukturę, połączenia konwolucyjne są często używane do uczenia się cech wysokiego poziomu danych. Na przykład w obrazie, dźwięku lub danych wideo wymiarowość przestrzenna lub czasowa może być dość jednolita.

Pakiety splotowe wykorzystują prostokątne jądra , które są posuwowane przez wymiary. Zasadniczo każde jądro definiuje zestaw wag stosowanych w lokalnych dzielnicach, nazywanych aplikacjami jądra. Każda aplikacja jądra odpowiada węzłowi w warstwie źródłowej, która jest nazywana węzłem centralnym. Wagi jądra są współdzielone między wieloma połączeniami. W pakiecie splotowym każde jądro jest prostokątne, a wszystkie aplikacje jądra mają taki sam rozmiar.

Pakiety splotowe obsługują następujące atrybuty:

InputShape definiuje wymiar warstwy źródłowej na potrzeby tego pakietu splotowego. Wartość musi być krotką dodatnich liczb całkowitych. Iloczyn liczb całkowitych musi być równy liczbie węzłów w warstwie źródłowej, ale w przeciwnym razie nie musi być zgodny z wymiarowością zadeklarowaną dla warstwy źródłowej. Długość tej krotki staje się wartością arity dla pakietu splotowego. Zazwyczaj arity odnosi się do liczby argumentów lub operandów, które może przyjąć funkcja.

Aby zdefiniować kształt i lokalizacje jądra, użyj atrybutów KernelShape, Stride, Padding, LowerPad i UpperPad:

  • KernelShape: (wymagane) Definiuje wymiarowość każdego jądra dla pakietu konwolucyjnego. Wartość musi być krotką dodatnich liczb całkowitych o długości równej arity pakietu. Każdy składnik tej krotki nie może być większy niż odpowiedni składnik inputShape.

  • Krok: (opcjonalnie) Definiuje przesuwane rozmiary kroków konwolucji (jeden rozmiar kroku dla każdego wymiaru), czyli odległość między węzłami centralnymi. Wartość musi być krotką dodatnich liczb całkowitych o długości, która jest arity pakietu. Każdy składnik tej krotki nie może być większy niż odpowiedni składnik jądraShape. Wartość domyślna to krotka ze wszystkimi składnikami równymi jednemu.

  • Udostępnianie: (opcjonalnie) Definiuje podział wagi dla każdego wymiaru konwolucji. Wartość może być pojedynczą wartością logiczną lub krotką wartości logicznych o długości, która jest wartością arity pakietu. Pojedyncza wartość logiczna jest rozszerzona, aby być krotką prawidłowej długości ze wszystkimi składnikami równymi określonej wartości. Wartość domyślna to krotka składająca się ze wszystkich wartości True.

  • MapCount: (opcjonalnie) Definiuje liczbę map funkcji dla pakietu konwolucyjnego. Wartość może być pojedynczą dodatnią liczbą całkowitą lub krotką dodatnich liczb całkowitych o długości, która jest arity pakietu. Pojedyncza wartość całkowita jest rozszerzona, aby być krotką prawidłowej długości z pierwszymi składnikami równymi określonej wartości i wszystkim pozostałym składnikom równym jednej. Domyślna wartość wynosi 1. Łączna liczba map funkcji jest produktem składników krotki. Faktoring tej całkowitej liczby składników określa sposób grupowania wartości mapy funkcji w węzłach docelowych.

  • Wagi: (opcjonalnie) Definiuje początkowe wagi pakietu. Wartość musi być krotką wartości zmiennoprzecinkowych o długości, która jest liczbą jąder razy liczbą wag na jądro, zgodnie z definicją w dalszej części tego artykułu. Domyślne wagi są generowane losowo.

Istnieją dwa zestawy właściwości, które kontrolują dopełnienie, właściwości są wzajemnie wykluczające:

  • Wypełnienie: (opcjonalnie) Określa, czy dane wejściowe mają być dopełniane przy użyciu domyślnego schematu wypełnienia. Wartość może być pojedynczą wartością logiczną lub może być krotką wartości logicznych o długości, która jest arity pakietu.

    Pojedyncza wartość logiczna jest rozszerzona, aby być krotką prawidłowej długości ze wszystkimi składnikami równymi określonej wartości.

    Jeśli wartość wymiaru ma wartość True, źródło jest logicznie wypełnione w tym wymiarze z komórkami o zerowej wartości w celu obsługi dodatkowych aplikacji jądra, tak aby centralne węzły pierwszego i ostatniego jądra w tym wymiarze to pierwsze i ostatnie węzły w tym wymiarze w tej warstwie źródłowej. W związku z tym liczba "fikcyjnych" węzłów w każdym wymiarze jest określana automatycznie, aby dopasować dokładnie (InputShape[d] - 1) / Stride[d] + 1 jądra do wyściełanej warstwy źródłowej.

    Jeśli wartość wymiaru to Fałsz, jądra są zdefiniowane tak, aby liczba węzłów po każdej stronie, które są pominięte, jest taka sama (do różnicy 1). Wartość domyślna tego atrybutu to krotka ze wszystkimi składnikami równymi Fałsz.

  • UpperPad i LowerPad: (opcjonalnie) Zapewniają większą kontrolę nad ilością dopełnienia do użycia. Ważne: te atrybuty można zdefiniować tylko wtedy, gdy właściwość Dopełnienie powyżej nie jest zdefiniowana. Wartości powinny być krotkami o wartości całkowitej z długościami, które są wartościami arity pakietu. Po określeniu tych atrybutów węzły "fikcyjne" są dodawane do dolnej i górnej części każdego wymiaru warstwy wejściowej. Liczba węzłów dodanych do dolnej i górnej części każdego wymiaru jest określana odpowiednio przez elementy LowerPad[i] i UpperPad[i].

    Aby upewnić się, że jądra odpowiadają tylko "rzeczywistym" węzłom, a nie "fikcyjnym" węzłom, muszą zostać spełnione następujące warunki:

    • Każdy składnik LowerPad musi być ściśle mniejszy niż KernelShape[d]/2.

    • Każdy składnik górnego tabletuPad nie może być większy niż KernelShape[d]/2.

    • Wartość domyślna tych atrybutów to krotka ze wszystkimi składnikami równymi 0.

      Ustawienie Dopełnienie = true umożliwia tak samo dopełnienie , jak jest potrzebne, aby zachować "środek" jądra wewnątrz "rzeczywistych" danych wejściowych. Spowoduje to zmianę wartości matematycznej na potrzeby obliczania rozmiaru danych wyjściowych. Ogólnie rzecz biorąc, rozmiar danych wyjściowych D jest obliczany jako D = (I - K) / S + 1, gdzie I jest rozmiarem wejściowym, K jest rozmiar jądra, S jest krokiem i / jest liczbą całkowitą (zaokrągloną w kierunku zera). W przypadku ustawienia UpperPad = [1, 1], rozmiar I danych wejściowych wynosi 29, a tym samym D = (29 - 5) / 2 + 1 = 13. Jednak gdy dopełnienie = prawda, zasadniczo I zostaje wyboiste przez K - 1; stąd D = ((28 + 4) - 5) / 2 + 1 = 27 / 2 + 1 = 13 + 1 = 14. Określając wartości dla upperPad i LowerPad , uzyskasz znacznie większą kontrolę nad dopełnienie niż w przypadku ustawienia padding = true.

Aby uzyskać więcej informacji na temat splotowych sieci i ich aplikacji, zobacz następujące artykuły:

Pakiety puli

Pakiet puli stosuje geometrię podobną do łączności konwolucyjnej, ale używa wstępnie zdefiniowanych funkcji do wartości węzłów źródłowych w celu uzyskania wartości węzła docelowego. W związku z tym pakiety buforowania nie mają stanu trenowania (wagi lub uprzedzenia). Pakiety puli obsługują wszystkie atrybuty splotowe, z wyjątkiem udostępniania, mapcount i wagi.

Zazwyczaj jądra podsumowane przez sąsiadujące jednostki puli nie nakładają się na siebie. Jeśli wartość Stride[d] jest równa KernelShape[d] w każdym wymiarze, uzyskana warstwa jest tradycyjną lokalną warstwą buforowania, która jest często stosowana w splotowych sieciach neuronowych. Każdy węzeł docelowy oblicza maksymalną lub średnią działań jądra w warstwie źródłowej.

Poniższy przykład ilustruje pakiet puli:

hidden P1 [5, 12, 12]
  from C1 max pool {
  InputShape  = [ 5, 24, 24];
   KernelShape = [ 1,  2,  2];
   Stride      = [ 1,  2,  2];
  }
  • Arity pakietu wynosi 3: czyli długość krotki InputShape, KernelShapei Stride.
  • Liczba węzłów w warstwie źródłowej to 5 * 24 * 24 = 2880.
  • Jest to tradycyjna lokalna warstwa buforowania, ponieważ funkcja KernelShape i Stride są równe.
  • Liczba węzłów w warstwie docelowej to 5 * 12 * 12 = 1440.

Aby uzyskać więcej informacji na temat warstw buforowania, zobacz następujące artykuły:

Pakiety normalizacji odpowiedzi

Normalizacja odpowiedzi to lokalny schemat normalizacji, który został po raz pierwszy wprowadzony przez Geoffrey Hinton, et al, w artykule ImageNet Classification with Deep Convolutional Neural Networks (Klasyfikacja sieci obrazów z głębokimi splotowymi sieciami neuronowymi).

Normalizacja odpowiedzi służy do uogólniania w sieciach neuronowych. Gdy jeden neuron jest wyzwalany na bardzo wysokim poziomie aktywacji, lokalna warstwa normalizacji odpowiedzi pomija poziom aktywacji otaczających neuronów. Odbywa się to przy użyciu trzech parametrów (α, β, i ) i kstruktury splotowej (lub kształtu sąsiedztwa). Każdy neuron w warstwie docelowej y odpowiada neuronowi x w warstwie źródłowej. Poziom aktywacji y jest podawany przez następującą formułę, gdzie f jest poziomem aktywacji neuronu i Nx jest jądrem (lub zestawem zawierającym neurony w sąsiedztwie x), zgodnie z definicją w następującej strukturze splotowej:

formuła dla struktury konwolucyjnej

Pakiety normalizacji odpowiedzi obsługują wszystkie atrybuty splotu, z wyjątkiem udostępniania, mapcount i wagi.

  • Jeśli jądro zawiera neurony na tej samej mapie co x, schemat normalizacji jest określany jako normalizacja mapy. Aby zdefiniować tę samą normalizację mapy, pierwsza współrzędna w pliku InputShape musi mieć wartość 1.

  • Jeśli jądro zawiera neurony w tej samej pozycji przestrzennej co x, ale neurony znajdują się w innych mapach, schemat normalizacji jest wywoływany w ramach normalizacji map. Ten typ normalizacji odpowiedzi implementuje formę hamowania bocznego inspirowanego typem znalezionym w rzeczywistych neuronach, tworząc konkurencję dla dużych poziomów aktywacji wśród danych wyjściowych neuronów obliczanych na różnych mapach. Aby zdefiniować normalizację map, pierwszą współrzędną musi być liczba całkowita większa niż jedna i nie większa niż liczba map, a pozostałe współrzędne muszą mieć wartość 1.

Ponieważ pakiety normalizacji odpowiedzi stosują wstępnie zdefiniowaną funkcję do wartości węzłów źródłowych w celu określenia wartości węzła docelowego, nie mają one stanu trenowania (wagi lub uprzedzenia).

Uwaga

Węzły w warstwie docelowej odpowiadają neuronom, które są centralnymi węzłami jądra. Jeśli na przykład KernelShape[d] jest dziwne, odpowiada KernelShape[d]/2 centralnemu węzłowi jądra. Jeśli KernelShape[d] jest nawet, węzeł centralny znajduje się w .KernelShape[d]/2 - 1 W związku z tym, jeśli Padding[d] ma wartość False, pierwsze i ostatnie KernelShape[d]/2 węzły nie mają odpowiednich węzłów w warstwie docelowej. Aby uniknąć tej sytuacji, zdefiniuj dopełnienie jako [true, true, ..., true].

Oprócz czterech opisanych wcześniej atrybutów pakiety normalizacji odpowiedzi obsługują również następujące atrybuty:

  • Alfa: (wymagane) Określa wartość zmiennoprzecinkową odpowiadającą α poprzedniej formule.
  • Beta: (wymagane) Określa wartość zmiennoprzecinkową odpowiadającą β poprzedniej formule.
  • Przesunięcie: (opcjonalnie) Określa wartość zmiennoprzecinkową odpowiadającą k poprzedniej formule. Wartość domyślna to 1.

W poniższym przykładzie zdefiniowano pakiet normalizacji odpowiedzi przy użyciu następujących atrybutów:

hidden RN1 [5, 10, 10]
from P1 response norm {
  InputShape  = [ 5, 12, 12];
  KernelShape = [ 1,  3,  3];
  Alpha = 0.001;
  Beta = 0.75;
  }
  • Warstwa źródłowa zawiera pięć map, z których każdy ma wymiar 12x12, łącznie w 1440 węzłach.
  • Wartość JądraShape wskazuje, że jest to ta sama warstwa normalizacji mapy, gdzie sąsiedztwo jest prostokątem 3x3.
  • Wartość domyślna dopełnienia to False, dlatego warstwa docelowa ma tylko 10 węzłów w każdym wymiarze. Aby uwzględnić jeden węzeł w warstwie docelowej odpowiadającej każdemu węzłowi w warstwie źródłowej, dodaj dopełnienie = [true, true, true]; i zmień rozmiar RN1 na [5, 12, 12].

Deklaracja udziału

Opcjonalnie platforma Net# obsługuje definiowanie wielu pakietów z wagami udostępnionymi. Wagi dwóch pakietów można udostępniać, jeśli ich struktury są takie same. Poniższa składnia definiuje pakiety z wagami udostępnionymi:

share-declaration:
  share    {    layer-list    }
  share    {    bundle-list    }
  share    {    bias-list    }

  layer-list:
    layer-name    ,    layer-name
    layer-list    ,    layer-name

  bundle-list:
    bundle-spec    ,    bundle-spec
    bundle-list    ,    bundle-spec

  bundle-spec:
    layer-name    =>     layer-name

  bias-list:
    bias-spec    ,    bias-spec
    bias-list    ,    bias-spec

  bias-spec:
    1    =>    layer-name

  layer-name:
    identifier

Na przykład następująca deklaracja udziału określa nazwy warstw, wskazując, że zarówno wagi, jak i uprzedzenia powinny być współużytkowane:

Const {
  InputSize = 37;
  HiddenSize = 50;
  }
input {
  Data1 [InputSize];
  Data2 [InputSize];
  }
hidden {
  H1 [HiddenSize] from Data1 all;
  H2 [HiddenSize] from Data2 all;
  }
output Result [2] {
  from H1 all;
  from H2 all;
  }
share { H1, H2 } // share both weights and biases
  • Funkcje wejściowe są podzielone na dwie warstwy wejściowe o równym rozmiarze.
  • Następnie warstwy ukryte obliczają funkcje wyższego poziomu na dwóch warstwach wejściowych.
  • Deklaracja udziału określa, że H1 i H2 muszą być obliczane w taki sam sposób z odpowiednich danych wejściowych.

Alternatywnie można to określić przy użyciu dwóch oddzielnych deklaracji udziałów w następujący sposób:

share { Data1 => H1, Data2 => H2 } // share weights
<!-- -->
    share { 1 => H1, 1 => H2 } // share biases

Można użyć krótkiej formy tylko wtedy, gdy warstwy zawierają pojedynczy pakiet. Ogólnie rzecz biorąc, udostępnianie jest możliwe tylko wtedy, gdy odpowiednia struktura jest identyczna, co oznacza, że mają taki sam rozmiar, taką samą geometrię splotową i tak dalej.

Przykłady użycia platformy Net#

W tej sekcji przedstawiono kilka przykładów sposobu używania platformy Net# do dodawania ukrytych warstw, definiowania sposobu interakcji ukrytych warstw z innymi warstwami i tworzenia sieci splotowych.

Definiowanie prostej niestandardowej sieci neuronowej: przykład "Hello World"

W tym prostym przykładzie pokazano, jak utworzyć model sieci neuronowej, który ma jedną ukrytą warstwę.

input Data auto;
hidden H [200] from Data all;
output Out [10] sigmoid from H all;

W przykładzie przedstawiono kilka podstawowych poleceń w następujący sposób:

  • Pierwszy wiersz definiuje warstwę wejściową (o nazwie Data). Gdy używasz słowa kluczowego auto , sieć neuronowa automatycznie uwzględnia wszystkie kolumny funkcji w przykładach wejściowych.
  • Drugi wiersz tworzy warstwę ukrytą. Nazwa H jest przypisywana do warstwy ukrytej, która ma 200 węzłów. Ta warstwa jest w pełni połączona z warstwą wejściową.
  • Trzeci wiersz definiuje warstwę wyjściową (o nazwie Out), która zawiera 10 węzłów wyjściowych. Jeśli sieć neuronowa jest używana do klasyfikacji, istnieje jeden węzeł wyjściowy na klasę. Sigmoid słowa kluczowego wskazuje, że funkcja wyjściowa jest stosowana do warstwy wyjściowej.

Definiowanie wielu ukrytych warstw: przykład przetwarzania obrazów

W poniższym przykładzie pokazano, jak zdefiniować nieco bardziej złożoną sieć neuronową z wieloma niestandardowymi warstwami ukrytymi.

// Define the input layers
input Pixels [10, 20];
input MetaData [7];

// Define the first two hidden layers, using data only from the Pixels input
hidden ByRow [10, 12] from Pixels where (s,d) => s[0] == d[0];
hidden ByCol [5, 20] from Pixels where (s,d) => abs(s[1] - d[1]) <= 1;

// Define the third hidden layer, which uses as source the hidden layers ByRow and ByCol
hidden Gather [100]
{
from ByRow all;
from ByCol all;
}

// Define the output layer and its sources
output Result [10]
{
from Gather all;
from MetaData all;
}

W tym przykładzie przedstawiono kilka funkcji języka specyfikacji sieci neuronowych:

  • Struktura ma dwie warstwy wejściowe i Pixels MetaData.
  • Warstwa Pixels jest warstwą źródłową dla dwóch pakietów połączeń z warstwami ByRow docelowymi i ByCol.
  • Warstwy i Result są warstwami Gather docelowymi w wielu pakietach połączeń.
  • Warstwa wyjściowa, Result, jest warstwą docelową w dwóch pakietach połączeń; jedna z drugą warstwą ukrytą Gather jako warstwą docelową, a druga z warstwą wejściową jako warstwą MetaData docelową.
  • Warstwy ByRow ukryte i ByCol, określają odfiltrowaną łączność przy użyciu wyrażeń predykatu. Dokładniej mówiąc, węzeł w ByRow lokalizacji [x, y] jest połączony z węzłami, w Pixels których pierwsza współrzędna indeksu jest równa pierwszej współrzędności węzła, x. Podobnie węzeł w ByCol lokalizacji [x, y] jest połączony z węzłami, w Pixels których współrzędna drugiego indeksu znajduje się w jednej ze współrzędnych drugiego węzła, y.

Definiowanie sieci splotowej dla klasyfikacji wieloklasowej: przykład rozpoznawania cyfr

Definicja poniższej sieci została zaprojektowana pod kątem rozpoznawania liczb i ilustruje niektóre zaawansowane techniki dostosowywania sieci neuronowej.

input Image [29, 29];
hidden Conv1 [5, 13, 13] from Image convolve
  {
  InputShape  = [29, 29];
  KernelShape = [ 5,  5];
  Stride      = [ 2,  2];
  MapCount    = 5;
  }
hidden Conv2 [50, 5, 5]
from Conv1 convolve
  {
  InputShape  = [ 5, 13, 13];
  KernelShape = [ 1,  5,  5];
  Stride      = [ 1,  2,  2];
  Sharing     = [false, true, true];
  MapCount    = 10;
  }
hidden Hid3 [100] from Conv2 all;
output Digit [10] from Hid3 all;
  • Struktura ma jedną warstwę wejściową. Image

  • Słowo kluczowe convolve wskazuje, że warstwy o nazwie Conv1 i Conv2 są warstwami splotowymi. Po każdej z tych deklaracji warstw następuje lista atrybutów splotu.

  • Sieć ma trzecią ukrytą warstwę , Hid3która jest w pełni połączona z drugą ukrytą warstwą Conv2.

  • Warstwa wyjściowa , Digitjest połączona tylko z trzecią ukrytą warstwą Hid3. Słowo kluczowe all wskazuje, że warstwa wyjściowa jest w pełni połączona z usługą Hid3.

  • Arity splotu wynosi trzy: długość krotki InputShape, , KernelShapeStridei Sharing.

  • Liczba wag na jądro to 1 + KernelShape\[0] * KernelShape\[1] * KernelShape\[2] = 1 + 1 * 5 * 5 = 26. Lub 26 * 50 = 1300.

  • Węzły w każdej ukrytej warstwie można obliczyć w następujący sposób:

    NodeCount\[0] = (5 - 1) / 1 + 1 = 5 NodeCount\[1] = (13 - 5) / 2 + 1 = 5 NodeCount\[2] = (13 - 5) / 2 + 1 = 5

  • Łączna liczba węzłów można obliczyć przy użyciu zadeklarowanej wymiarowości warstwy [50, 5, 5], w następujący sposób: MapCount * NodeCount\[0] * NodeCount\[1] * NodeCount\[2] = 10 * 5 * 5 * 5

  • Ponieważ Sharing[d] parametr ma wartość False tylko dla d == 0parametru , liczba jąder to MapCount * NodeCount\[0] = 10 * 5 = 50.

Podziękowania

Język net# do dostosowywania architektury sieci neuronowych został opracowany w firmie Microsoft przez Shon Katzenberger (architekt, uczenie maszynowe) i Alexey Kamenev (inżynier oprogramowania, Microsoft Research). Jest ona używana wewnętrznie dla projektów i aplikacji uczenia maszynowego, od wykrywania obrazów do analizy tekstu. Aby uzyskać więcej informacji, zobacz Sieci neuronowe w usłudze Machine Learning Studio — wprowadzenie do sieci#