Курс Эндрю Ына Машинное Обучение в Стэнфордском университете (CS229 - Machine Learning)

Разделы сайта


Курс Эндрю Ына Машинное Обучение в Стэнфордском университете (CS229 - Machine Learning)

С 2011 года на протяжении многих лет лучшим и самым популярным в мире начальным курсом по Машинному Обучению (Machine Learning) является бесплатный курс Эндрю Ына (Andrew Ng) на Курсере (Coursera). Andrew Ng является VP & Chief Scientist of Baidu; Co-Chairman and Co-Founder of Coursera; co-founded and led Google Brain и an Adjunct Professor (ранее associate professor и Director of the AI Lab) в Stanford University. Курс дает базовое понимание основ Машинного Обучения. Практические примеры и задания используют Octave, что, по мнению многих, является основным недостатком курса. Эндрю Ын отвечает, что для вводного курса Octave проще и понятнее, чем R или Python. Я все же для себя пришел к выводу, что повторить задания на Python просто необходимо, чтобы действительно понять и структуру представленных данных и методы решения. Мои (и не только мои) решения с использованием Python можно найти в моем репозитории на GitHub. Я делал на Python все задания начиная с пятой недели.

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

Определение термина Машинное Обучение от Артура Самуэля: "Machine Learning is the field of study that gives computers the ability to learn without being explicitly programmed", т.е. "область исследования, которая дает компьютерам возможность учиться без явного программирования".

Определение термина Машинное Обучение от Тома Митчелла: "A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P, if its performance at tasks in T, as measured by P, improves with experience E.", т.е. "говорят, что компьютерная программа учится на опыте E по отношению к некоторому классу задач T и измерению производительности P, если ее производительность при выполнении задач в T, измеренная P, улучшается с опытом E".

Пример: игра в шашки. E = опыт, полученный от многочисленных партий. T = задача игры в шашки. P = вероятность того, что программа выиграет следующую игру.

  • GNU Octave (официальный сайт).
  • Введение в Octave для инженеров и математиков. Авторы: Е.Р. Алексеев, О.В. Чеснокова
  • Supervised learning. CS229 Lecture notes by Andrew Ng.

  • Неделя 1. Градиентный спуск для линейной регрессии с одной переменной.
  • Неделя 2. Градиентный спуск для множественной линейной регрессии.
  • Неделя 3. Функция потерь (cost funtction) и градиентный спуск для логистической регрессии.
  • Неделя 3. Регуляризация.
  • Неделя 4. Нейронные сети. Основы.
  • Неделя 5. Нейронные сети. Cost Function и Метод обратного распространения ошибки (backpropagation).
  • Неделя 6. Советы по применению Машинного Обучения.
  • Целью моделей "Обучение с учителем" (Supervised learning) является поиск параметров (весов), которые минимизируют функцию потерь (Cost function). По размерности независимой переменной $x$ можно выделить однофакторные (univariable) и многофакторые (multivariable) модели. Если независимая переменная $x^{(i)}$ является скалярным значением, то имеем одинарную (univariate) модель. Когда независимая переменная является многомерной, то есть представлена вектором, получаем множественную (multivariate ) модель. В последующих примерах, это поиск $\theta_n$ для каждой независимой переменной $x_n$ с использованием линейной регрессии. Отличная статья с примерами кода на Python: Линейные модели: простая регрессия. Начало этой статьи с описанием многообразия линейных моделей здесь .

    Определение термина Cost function (loss function, error function, функция потерь) - это мера того, насколько ошибочна модель с точки зрения ее способности оценивать взаимосвязь между $\theta$ и $y$. Обычно это выражается разницей или расстоянием между прогнозируемым и фактическим значением искомого параметра: $$J(\theta) =\frac{1}{2m}\sum \limits_{i=1}^{m} \left(h_\theta(x^{(i)})-y^{(i)}\right)^2$$ где $J(\theta) =$ $J(\theta_0, \theta_1,\theta_2, ..., \theta_n)$;
    $h_\theta(x)=$ $\theta_0+\theta_1 x_1+\theta_2 x_2+...+\theta_n x_n$.
    Если сделать так, что $x_0=1$, то $h_\theta(x)$ можно записать как $\sum\limits_{i=1}^{n} \theta_i x_i$ $=\theta^Tx$. Соответственно лучший код на Octave для этого задания:

    computeCostMulti.m :

    function J = computeCostMulti(X, y, theta)
                  
      %   COMPUTECOSTMULTI Compute cost for linear regression with multiple variables
      %   J = COMPUTECOSTMULTI(X, y, theta) computes the cost of using theta as the
      %   parameter for linear regression to fit the data points in X and y
    
      %   Initialize some useful values
      m = length(y); % number of training examples
    
      %   You need to return the following variables correctly 
      J = 0;
    
      % ====================== YOUR CODE HERE ======================
      %   Instructions: Compute the cost of a particular choice of theta
      %               You should set J to the cost.
    
      J = (1/(2*m))*(sum(((X*theta)-y).^2));
    
      % =========================================================================
    
    end

    Про назначение коэффициента $\frac{1}{2m}$ в функции потерь можно прочитать в ответах на следующие вопросы: 1. Почему в функции потерь (cost function) используется формула средней квадратичной ошибки (mean squared error, MSE)?, 2. Зачем нужно делить на $2m$?, 3. Функция потерь (cost function) в Методе наименьших квадратов (МНК, Ordinary Least Squares, OLS) регрессионного анализа.

    Градиентный спуск

    Определение градиента
    Почему вектор градиента всегда должен быть направлен в возрастающем направлении? Доказательство.

    Определение термина Gradient descent (Градиентный спуск) - метод нахождения локального экстремума (минимума или максимума) функции с помощью движения вдоль градиента. $$\theta_j := \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta)$$ где $j=0, 1, 2...n$, а $n$ - количество шагов, необходимых для вычисления оптимального значения $\theta$;
    $\alpha$ - шаг метода Градиентный спуск, скорость обучения. Основное правило: при каждом шаге значение $\theta_j$ должно уменьшаться, поэтому значение $\alpha$ не должно быть слишком большим. Но если значение $\alpha$ очень маленькое, то метод будет работать очень долго. Поэтому всегда требуется искать золотую середину.
    $\frac{\partial}{\partial \theta_j} J(\theta)$ - частная производная, которая равна $\frac{\partial}{\partial \theta_j} \frac{1}{2m}\sum \limits_{i=1}^{m} \left(h_\theta(x^{(i)})-y^{(i)}\right)^2$ = $2 \cdot \frac{1}{2m} \left(h_\theta(x^{(i)})-y^{(i)}\right) \cdot \frac{\partial}{\partial \theta_j} \left(h_\theta(x^{(i)})-y^{(i)}\right)$ = $\frac{1}{m} \left(h_\theta(x^{(i)})-y^{(i)}\right) \cdot \frac{\partial}{\partial \theta_j} \left(\sum \limits_{i=1}^{m} \theta_i x^{(i)}_j - y^{(i)}\right)$ = $\frac{1}{m} \left(h_\theta(x^{(i)})-y^{(i)}\right) x^{(i)}_j$, в итоге получаем: $$\theta_j := \theta_j + \alpha \frac{1}{m} \left(y^{(i)}-h_\theta(x^{(i)})\right) x^{(i)}_j$$

    Код на Octave для заданий второй недели по определению шага градиентного спуска: theta = theta -((1/m) * ((X * theta) - y)' * X)' * alpha.

    gradientDescentMulti.m :

    function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
                    
      %   GRADIENTDESCENTMULTI Performs gradient descent to learn theta
      %   theta = GRADIENTDESCENTMULTI(x, y, theta, alpha, num_iters) updates theta by
      %   taking num_iters gradient steps with learning rate alpha
    
      % Initialize some useful values
      m = length(y); % number of training examples
      J_history = zeros(num_iters, 1);
    
      for iter = 1:num_iters
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: Perform a single gradient step on the parameter vector
      %               theta. 
      %
      % Hint: While debugging, it can be useful to print out the values
      %       of the cost function (computeCostMulti) and gradient here.
      %
    
      %%%%%%%% CORRECT %%%%%%%%%%   
      error = (X * theta) - y;
      theta = theta - ((alpha/m) * X'*error);
      %%%%%%%%%%%%%%%%%%%%%%%%%%%
    
      % ============================================================
    
      % Save the cost J in every iteration    
      J_history(iter) = computeCostMulti(X, y, theta);
    
      end
    end

    Если features (признаки) отличаются на порядки, то их масштабирование существенно ускоряет работу метода градиентного спуска. Эта процедура называется Feature scaling.

    featureNormalize.m :

    function [X_norm, mu, sigma] = featureNormalize(X)
                        
      %   FEATURENORMALIZE Normalizes the features in X 
      %   FEATURENORMALIZE(X) returns a normalized version of X where
      %   the mean value of each feature is 0 and the standard deviation
      %   is 1. This is often a good preprocessing step to do when
      %   working with learning algorithms.
    
      %   You need to set these values correctly
      X_norm = X;
      mu = zeros(1, size(X, 2));
      sigma = zeros(1, size(X, 2));
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: First, for each feature dimension, compute the mean
      %               of the feature and subtract it from the dataset,
      %               storing the mean value in mu. Next, compute the 
      %               standard deviation of each feature and divide
      %               each feature by it's standard deviation, storing
      %               the standard deviation in sigma. 
      %
      %               Note that X is a matrix where each column is a 
      %               feature and each row is an example. You need 
      %               to perform the normalization separately for 
      %               each feature. 
      %
      % Hint: You might find the 'mean' and 'std' functions useful.
      %       
    
      mu = mean(X);
      sigma = std(X);
      X_norm = (X - mu)./sigma;
    
      % ============================================================
    end

    Помимо градиентного спуска можно использовать метод нормальных уравнений (the normal equations). Вот пост про этот метод.

    normalEqn.m :

    function [theta] = normalEqn(X, y)
      
      %   NORMALEQN Computes the closed-form solution to linear regression 
      %   NORMALEQN(X,y) computes the closed-form solution to linear 
      %   regression using the normal equations.
    
      theta = zeros(size(X, 2), 1);
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: Complete the code to compute the closed form solution
      %               to linear regression and put the result in theta.
      %
    
      % ---------------------- Sample Solution ----------------------
    
      theta = pinv(X'*X)*X'*y;
    
      % -------------------------------------------------------------
      % ============================================================
    end

    Логистическая регрессия

    Цель логистической регрессии, как и любого классификатора, состоит в том, чтобы выяснить, каким образом разделить данные, чтобы обеспечить точное предсказание класса данного наблюдения с использованием информации, присутствующей в его признаках (features).

    Логистическая функция (сигмоида): $$\Large{h_\theta }\left( x \right) = \frac{1}{1 + {e^{ - {\theta ^T}x}}}$$

    ее вероятностная интерпритация ${h _\theta }\left( {x _i} \right) = {\rm{P}}\left( {{y _i} = 1|{x _i};\theta } \right)$.

    sigmoid.m :

    function g = sigmoid(z)
      %SIGMOID Compute sigmoid function
      %   g = SIGMOID(z) computes the sigmoid of z.
    
      % You need to return the following variables correctly 
      g = zeros(size(z));
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: Compute the sigmoid of each value of z (z can be a matrix,
      %               vector or scalar).
      g = 1./(1+exp(-z));
    
      % =============================================================
    end
    

    predict.m :

    function p = predict(theta, X)
      %PREDICT Predict whether the label is 0 or 1 using learned logistic 
      %regression parameters theta
      %   p = PREDICT(theta, X) computes the predictions for X using a 
      %   threshold at 0.5 (i.e., if sigmoid(theta'*x) >= 0.5, predict 1)
    
      m = size(X, 1); % Number of training examples
    
      % You need to return the following variables correctly
      
      p = zeros(m, 1);
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: Complete the following code to make predictions using
      %               your learned logistic regression parameters. 
      %               You should set p to a vector of 0's and 1's
      %
      % Dimentions:
      % X     =  m x (n+1)
      % theta = (n+1) x 1
    
      p=(sigmoid(X*theta)>=0.5);
    
      %p = double(sigmoid(X * theta)>=0.5);
      % =========================================================================
    end
    

    Функция потерь логистической регрессии (Cost function for logistic regression): $$J\left( \theta \right) = \frac{1}{m}\sum\limits_{i = 1}^m {\rm{Cost}({h _\theta }\left( {x _i} \right),{y _i})}$$, где $\operatorname{Cost}(h_\theta(x),y) =$ $\begin{cases} -\log(h_\theta(x)), & \text{if $y$ = 1} \\ -\log(1-h_\theta(x)), & \text{if $y$ = 0} \end{cases}$

    или более кратко ${\rm{Cost}}({h _\theta }\left( x \right),y) =$ $- y\log \left( {{h _\theta }\left( x \right)} \right) -$ $\left( {1 - y} \right)\log \left( {1 - {h _\theta }\left( x \right)} \right)$.

    В итоге функция потерь логистической регрессии имеет вид:

    $J\left( \theta \right) =$ $\frac{1}{m}\sum\limits _{i = 1}^m { - {y _i}\log \left( {{h _\theta }\left( {x _i} \right)} \right) -}$ ${\left( {1 - {y _i}} \right)\log \left( {1 - {h _\theta }\left( {x _i} \right)} \right)}$.

    Здесь подробное объяснение, как взять частную производную фунции потерь логистической регрессии в алгоритме градиентного спуска: ${\theta _j}: = {\theta _j} - \alpha \frac{\partial }{\partial {\theta _j}}J\left( \theta \right)$.

    costFunction.m :

    function [J, grad] = costFunction(theta, X, y)
        
      %   COSTFUNCTION Compute cost and gradient for logistic regression
      %   J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the
      %   parameter for logistic regression and the gradient of the cost
      %   w.r.t. to the parameters.
    
      % Initialize some useful values
      m = length(y); % number of training examples
    
      % You need to return the following variables correctly 
      J = 0;
      grad = zeros(size(theta));
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: Compute the cost of a particular choice of theta.
      %               You should set J to the cost.
      %               Compute the partial derivatives and set grad to the partial
      %               derivatives of the cost w.r.t. each parameter in theta
      %
      % Note: grad should have the same dimensions as theta
      %
      %DIMENSIONS: 
      %   theta = (n+1) x 1
      %   X     = m x (n+1)
      %   y     = m x 1
      %   grad  = (n+1) x 1
      %   J     = Scalar
    
      z = X * theta;      % m x 1
      h_x = sigmoid(z);   % m x 1 
    
      J = (1/m)*sum((-y.*log(h_x))-((1-y).*log(1-h_x))); % scalar
    
      grad = (1/m)* (X'*(h_x-y));     % (n+1) x 1
    
      % =============================================================
    
    end
    Градиентный спуск — метод оптимизации первого порядка (первая производная). Вот более сложные и быстрые способы оптимизации $\theta$, которые могут быть использованы вместо метода градиентного спуска:
    Conjugate gradient method (метод сопряженных градиентов). Подробное описание алгоритма в статье Jonathan Richard Shewchuk от 1994 года "Введение в метод сопряженного градиента без мучительной боли"
    Метод BFGS - Алгоритм Бройдена — Флетчера — Гольдфарба — Шанно (англ. Broyden — Fletcher — Goldfarb — Shanno algorithm)
    Метод Limited-memory BFGS - (L-BFGS or LM-BFGS)
    Поиск минимума нелинейной функции нескольких переменных без ограничения на переменные можно осуществлять с помощью встроенной в Matlab/Octave функции fminunc. Она позволяет использовать предварительно заданные командой optimset порог сходимости для значения целевой функции, вектор градиентов options, grad-obj, матрицу Гесса, функцию умножения матрицы Гесса или график разреженности матрицы Гесса целевой функции:
    Документация на MathWorks
    Практикум по решению задач оптимизации в пакете MATLAB

    Регуляризация

    Регуляризация в машинном обучении — метод добавления некоторой дополнительной информации к условию с целью решить некорректно поставленную задачу или предотвратить переобучение.

    Функция потерь для линейной регрессии с учетом регуляризации
    Регуляризация линейной регрессии
    Метод градиентного спуска для линейной модели регрессии с учетом регуляризации
    Метод градиентного спуска для линейной модели регрессии с учетом регуляризации
    Функция потерь для логистической регрессии с учетом регуляризации
    Регуляризация логистической регрессии
    Метод градиентного спуска для логистической регрессии с учетом регуляризации
    Метод градиентного спуска для логистической регрессии с учетом регуляризации
    Метод градиентного спуска для логистической регрессии с учетом регуляризации

    costFunctionReg.m :

    function [J, grad] = costFunctionReg(theta, X, y, lambda)
        %COSTFUNCTIONREG Compute cost and gradient for logistic regression with regularization
      %   J = COSTFUNCTIONREG(theta, X, y, lambda) computes the cost of using
      %   theta as the parameter for regularized logistic regression and the
      %   gradient of the cost w.r.t. to the parameters. 
    
      % Initialize some useful values
      m = length(y); % number of training examples
    
      % You need to return the following variables correctly 
      J = 0;
      grad = zeros(size(theta));
    
      % ====================== YOUR CODE HERE ======================
      % Instructions: Compute the cost of a particular choice of theta.
      %               You should set J to the cost.
      %               Compute the partial derivatives and set grad to the partial
      %               derivatives of the cost w.r.t. each parameter in theta
    
      %DIMENSIONS: 
      %   theta = (n+1) x 1
      %   X     = m x (n+1)
      %   y     = m x 1
      %   grad  = (n+1) x 1
      %   J     = Scalar
    
      z = X * theta;      % m x 1
      h_x = sigmoid(z);  % m x 1 
    
      reg_term = (lambda/(2*m)) * sum(theta(2:end).^2);
    
      J = (1/m)*sum((-y.*log(h_x))-((1-y).*log(1-h_x))) + reg_term; % scalar
    
      grad(1) = (1/m)* (X(:,1)'*(h_x-y));                                  % 1 x 1
      grad(2:end) = (1/m)* (X(:,2:end)'*(h_x-y))+(lambda/m)*theta(2:end);  % n x 1
    
      % =============================================================
    end

    Неделя 4. Нейронные сети. Основы.

    простейшая нейросеть

    Код для lrCostFunction.m такой же как и в costFunctionReg.m из предыдущего урока.

    Попробуйте запустить следующие примеры кода в Octave перед решением задач этой недели:
  • [1] Работа логического оператора "==".
  • [2] Способ копирования вектора в матрицу. Cинтаксис "(2,:)" означает "используй все колонки второй строки".
  • [3] Добавление первой колонки в матрицу.
  • [val, idx] = max(a); где val - максимальное значение и idx - его индекс. Примеры использования функции max().
  • % ====================== 1 ======================
      a = 1:10
      b = 3
      a == b
    
    % ====================== 2 ======================
      Q = zeros(5,3)
      v = [1 2 3]'
      Q(2,:) = v
    
    % ====================== 3 ======================
      Q = magic(3)
      m = size(Q,1)
      Q = [ones(m,1) Q]
    
    
    

    oneVsAll.m :

    function [all_theta] = oneVsAll(X, y, num_labels, lambda)
        %ONEVSALL trains multiple logistic regression classifiers and returns all
        %the classifiers in a matrix all_theta, where the i-th row of all_theta 
        %corresponds to the classifier for label i
        %   [all_theta] = ONEVSALL(X, y, num_labels, lambda) trains num_labels
        %   logistic regression classifiers and returns each of these classifiers
        %   in a matrix all_theta, where the i-th row of all_theta corresponds 
        %   to the classifier for label i
    
        % num_labels = No. of output classifier (Here, it is 10)
    
        % Some useful variables
        m = size(X, 1);        % No. of Training Samples == No. of Images : (Here, 5000) 
        n = size(X, 2);        % No. of features == No. of pixels in each Image : (Here, 400)
    
        % You need to return the following variables correctly 
        all_theta = zeros(num_labels, n + 1);
        %DIMENSIONS: num_labels x (input_layer_size+1) == num_labels x (no_of_features+1) == 10 x 401
    
        %DIMENSIONS: X = m x input_layer_size
        %Here, 1 row in X represents 1 training Image of pixel 20x20
    
        % Add ones to the X data matrix
        X = [ones(m, 1) X];   %DIMENSIONS: X = m x (input_layer_size+1) = m x (no_of_features+1)
    
        % ====================== YOUR CODE HERE ======================
        % Instructions: You should complete the following code to train num_labels
        %               logistic regression classifiers with regularization
        %               parameter lambda. 
        %
        % Hint: theta(:) will return a column vector.
        %
        % Hint: You can use y == c to obtain a vector of 1's and 0's that tell you
        %       whether the ground truth is true/false for this class.
        %
        % Note: For this assignment, we recommend using fmincg to optimize the cost
        %       function. It is okay to use a for-loop (for c = 1:num_labels) to
        %       loop over the different classes.
        %
        %       fmincg works similarly to fminunc, but is more efficient when we
        %       are dealing with large number of parameters.
        %
        % Example Code for fmincg:
        %
        %     % Set Initial theta
        %     initial_theta = zeros(n + 1, 1);
        %     
        %     % Set options for fminunc
        %     options = optimset('GradObj', 'on', 'MaxIter', 50);
        % 
        %     % Run fmincg to obtain the optimal theta
        %     % This function will return theta and the cost 
        %     [theta] = ...
        %         fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
        %                 initial_theta, options);
        %
    
        initial_theta = zeros(n+1, 1);
        options = optimset('GradObj', 'on', 'MaxIter', 50);
    
        for c=1:num_labels
        all_theta(c,:) = ...
                 fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
                         initial_theta, options);
        end
    
        % =========================================================================
      end

    predictOneVsAll.m :

      function p = predictOneVsAll(all_theta, X)
        %PREDICT Predict the label for a trained one-vs-all classifier. The labels
        %are in the range 1..K, where K = size(all_theta, 1).
        %  p = PREDICTONEVSALL(all_theta, X) will return a vector of predictions
        %  for each example in the matrix X. Note that X contains the examples in
        %  rows. all_theta is a matrix where the i-th row is a trained logistic
        %  regression theta vector for the i-th class. You should set p to a vector
        %  of values from 1..K (e.g., p = [1; 3; 1; 2] predicts classes 1, 3, 1, 2
        %  for 4 examples)
    
        m = size(X, 1);     % No. of Input Examples to Predict (Each row = 1 Example)
        num_labels = size(all_theta, 1); %No. of Ouput Classifier
    
        % You need to return the following variables correctly
        p = zeros(size(X, 1), 1);    % No_of_Input_Examples x 1 == m x 1
    
        % Add ones to the X data matrix
        X = [ones(m, 1) X];
    
        % ====================== YOUR CODE HERE ======================
        % Instructions: Complete the following code to make predictions using
        %               your learned logistic regression parameters (one-vs-all).
        %               You should set p to a vector of predictions (from 1 to
        %               num_labels).
        %
        % Hint: This code can be done all vectorized using the max function.
        %       In particular, the max function can also return the index of the
        %       max element, for more information see 'help max'. If your examples
        %       are in rows, then, you can use max(A, [], 2) to obtain the max
        %       for each row.
        %
        % num_labels = No. of output classifier (Here, it is 10)
        % DIMENSIONS:
        % all_theta = 10 x 401 = num_labels x (input_layer_size+1) == num_labels x (no_of_features+1)
    
        prob_mat = X * all_theta';     % 5000 x 10 == no_of_input_image x num_labels
        [prob, p] = max(prob_mat,[],2); % m  x 1 
        %returns maximum element in each row  == max. probability and its index for each input image
        %p: predicted output (index)
        %prob: probability of predicted output
    
        %%%%%%%% WORKING: Computation per input image %%%%%%%%%
        % for i = 1:m                               % To iterate through each input sample
        %     one_image = X(i,:);                   % 1 x 401 == 1 x no_of_features
        %     prob_mat = one_image * all_theta';    % 1 x 10  == 1 x num_labels
        %     [prob, out] = max(prob_mat);
        %     %out: predicted output
        %     %prob: probability of predicted output
        %     p(i) = out;
        % end
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
        %%%%%%%% WORKING %%%%%%%%%
        % for i = 1:m
        %     RX = repmat(X(i,:),num_labels,1);
        %     RX = RX .* all_theta;
        %     SX = sum(RX,2);
        %     [val, index] = max(SX);
        %     p(i) = index;
        % end
        %%%%%%%%%%%%%%%%%%%%%%%%%%
        % =========================================================================
      end
    

    Сети прямого распространения (Feedforward neural network) (feedforward сети) - искусственные нейронные сети, в которых сигнал распространяется строго от входного слоя к выходному. В обратном направлении сигнал не распространяется.

    predict.m :

    
      function p = predict(Theta1, Theta2, X)
        %PREDICT Predict the label of an input given a trained neural network
        %   p = PREDICT(Theta1, Theta2, X) outputs the predicted label of X given the
        %   trained weights of a neural network (Theta1, Theta2)
    
        % Useful values
        m = size(X, 1);
        num_labels = size(Theta2, 1);
    
        % You need to return the following variables correctly 
        p = zeros(size(X, 1), 1);  % m x 1
    
        % ====================== YOUR CODE HERE ======================
        % Instructions: Complete the following code to make predictions using
        %               your learned neural network. You should set p to a 
        %               vector containing labels between 1 to num_labels.
        %
        % Hint: The max function might come in useful. In particular, the max
        %       function can also return the index of the max element, for more
        %       information see 'help max'. If your examples are in rows, then, you
        %       can use max(A, [], 2) to obtain the max for each row.
        %
        %DIMENSIONS:
        % theta1 = 25 x 401
        % theta2 = 10 x 26
    
        % layer1 (input)  = 400 nodes + 1bias
        % layer2 (hidden) = 25 nodes + 1bias 
        % layer3 (output) = 10 nodes
        % 
        % theta dimensions = S_(j+1) x ((S_j)+1)
        % theta1 = 26 x 401
        % theta2 = 10 x 26
    
        % theta1:
        %     1st row indicates: theta corresponding to all nodes from layer1 connecting to for 1st node of layer2
        %     2nd row indicates: theta corresponding to all nodes from layer1 connecting to for 2nd node of layer2
        %     and
        %     1st Column indicates: theta corresponding to node1 from layer1 to all nodes in layer2
        %     2nd Column indicates: theta corresponding to node2 from layer1 to all nodes in layer2
        %     
        % theta2:
        %     1st row indicates: theta corresponding to all nodes from layer2 connecting to for 1st node of layer3
        %     2nd row indicates: theta corresponding to all nodes from layer2 connecting to for 2nd node of layer3
        %     and
        %     1st Column indicates: theta corresponding to node1 from layer2 to all nodes in layer3
        %     2nd Column indicates: theta corresponding to node2 from layer2 to all nodes in layer3
    
        a1 = [ones(m,1) X]; % 5000 x 401 == no_of_input_images x no_of_features % Adding 1 in X 
        %No. of rows = no. of input images
        %No. of Column = No. of features in each image
    
        z2 = a1 * Theta1';  % 5000 x 25
        a2 = sigmoid(z2);   % 5000 x 25
    
        a2 =  [ones(size(a2,1),1) a2];  % 5000 x 26
    
        z3 = a2 * Theta2';  % 5000 x 10
        a3 = sigmoid(z3);  % 5000 x 10
    
        [prob, p] = max(a3,[],2);
        %returns maximum element in each row  == max. probability and its index for each input image
        %p: predicted output (index)
        %prob: probability of predicted output
    
        % =========================================================================
      end
    

    Неделя 5. Нейронные сети. Cost Function и Метод обратного распространения ошибки (англ. backpropagation).

    Нейросеть. Метод обратного распространения ошибки. Backpropagation.
    Нейросеть. Метод обратного распространения ошибки. Backpropagation.

    Функция потерь для нейронной сети:

    Функция потерь для нейронной сети. The cost function for the neuron network

    Функция потерь для данной задачи, где нейронная сеть состоит из одного внутреннего слоя:

    Функция потерь для нейронной сети. The cost function for the neuron network
    Дополнительные ресурсы для лучшего понимания:
  • Jeremy Jordan. Нейронные сети: обучение методом обратного распространения ошибки (backpropagation)..
  • Michael Nielsen. Как работает алгоритм обратного распространения ошибки (backpropagation)..
  • Gradient checking.

  • [1] Объяснение синтексиса Y = eye(num_labels)(y, :)
  • [2] The gradient of the sigmoid function.
  • [3] Другой вариант для The gradient of the sigmoid function.
  • % ====================== 1 ======================
      num_labels = 5
      I = eye(num_labels)
      y = [2 3 3 1 5 4 4 4]
      Y = I(y, :)
    % ====================== 2 ======================
      g= sigmoid(z).*(1-sigmoid(z));
    % ====================== 3 ======================
      g = (1./(1+exp(-z))).*(1-1./(1+exp(-z)));
    

    nnCostFunction.m :

        function [J, grad] = nnCostFunction(nn_params, ...
              input_layer_size, ...
              hidden_layer_size, ...
              num_labels, ...
              X, y, lambda)
          %NNCOSTFUNCTION Implements the neural network cost function for a two layer
          %neural network which performs classification
          %   [J grad] = NNCOSTFUNCTON(nn_params, hidden_layer_size, num_labels, ...
          %   X, y, lambda) computes the cost and gradient of the neural network. The
          %   parameters for the neural network are "unrolled" into the vector
          %   nn_params and need to be converted back into the weight matrices.
          %
          %   The returned parameter grad should be a "unrolled" vector of the
          %   partial derivatives of the neural network.
          %
    
          % Reshape nn_params back into the parameters Theta1 and Theta2, the weight matrices
          % for our 2 layer neural network
          % DIMENSIONS:
          % Theta1 = 25 x 401
          % Theta2 = 10 x 26
    
          Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...
              hidden_layer_size, (input_layer_size + 1));
    
          Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...
              num_labels, (hidden_layer_size + 1));
    
          % Setup some useful variables
          m = size(X, 1);
    
          % You need to return the following variables correctly
          J = 0;
          Theta1_grad = zeros(size(Theta1)); %25 x401
          Theta2_grad = zeros(size(Theta2)); %10 x 26
    
          % ====================== YOUR CODE HERE ======================
          % Instructions: You should complete the code by working through the
          %               following parts.
          %
          % Part 1: Feedforward the neural network and return the cost in the
          %         variable J. After implementing Part 1, you can verify that your
          %         cost function computation is correct by verifying the cost
          %         computed in ex4.m
          %
          % Part 2: Implement the backpropagation algorithm to compute the gradients
          %         Theta1_grad and Theta2_grad. You should return the partial derivatives of
          %         the cost function with respect to Theta1 and Theta2 in Theta1_grad and
          %         Theta2_grad, respectively. After implementing Part 2, you can check
          %         that your implementation is correct by running checkNNGradients
          %
          %         Note: The vector y passed into the function is a vector of labels
          %               containing values from 1..K. You need to map this vector into a
          %               binary vector of 1's and 0's to be used with the neural network
          %               cost function.
          %
          %         Hint: We recommend implementing backpropagation using a for-loop
          %               over the training examples if you are implementing it for the
          %               first time.
          %
          % Part 3: Implement regularization with the cost function and gradients.
          %
          %         Hint: You can implement this around the code for
          %               backpropagation. That is, you can compute the gradients for
          %               the regularization separately and then add them to Theta1_grad
          %               and Theta2_grad from Part 2.
          %
    
          %%%%%%%%%%% Part 1: Calculating J w/o Regularization %%%%%%%%%%%%%%%
    
          X = [ones(m,1), X];  % Adding 1 as first column in X
    
          a1 = X; % 5000 x 401
    
          z2 = a1 * Theta1';  % m x hidden_layer_size == 5000 x 25
          a2 = sigmoid(z2); % m x hidden_layer_size == 5000 x 25
          a2 = [ones(size(a2,1),1), a2]; % Adding 1 as first column in z = (Adding bias unit) % m x (hidden_layer_size + 1) == 5000 x 26
    
          z3 = a2 * Theta2';  % m x num_labels == 5000 x 10
          a3 = sigmoid(z3); % m x num_labels == 5000 x 10
    
          %Converting y into vector of 0's and 1's for multi-class classification
          y = eye(num_labels)(y,:);
    
          %Costfunction Without regularization
          J = (1/m) * sum(sum((-y.*log(a3))-((1-y).*log(1-a3))));  %scalar
    
    
          %%%%%%%%%%% Part 2: Implementing Backpropogation for Theta_gra w/o Regularization %%%%%%%%%%%%%
    
          %%%%%%% WORKING: Backpropogation using for loop %%%%%%%
          % for t=1:m
          %     % Here X is including 1 column at begining
          %     
          %     % for layer-1
          %     a1 = X(t,:)'; % (n+1) x 1 == 401 x 1
          %     
          %     % for layer-2
          %     z2 = Theta1 * a1;  % hidden_layer_size x 1 == 25 x 1
          %     a2 = [1; sigmoid(z2)]; % (hidden_layer_size+1) x 1 == 26 x 1
          %   
          %     % for layer-3
          %     z3 = Theta2 * a2; % num_labels x 1 == 10 x 1    
          %     a3 = sigmoid(z3); % num_labels x 1 == 10 x 1    
          % 
          %     yVector = (1:num_labels)'==y(t); % num_labels x 1 == 10 x 1    
          %     
          %     %calculating delta values
          %     delta3 = a3 - yVector; % num_labels x 1 == 10 x 1    
          %     
          %     delta2 = (Theta2' * delta3) .* [1; sigmoidGradient(z2)]; % (hidden_layer_size+1) x 1 == 26 x 1
          %     
          %     delta2 = delta2(2:end); % hidden_layer_size x 1 == 25 x 1 %Removing delta2 for bias node  
          %     
          %     % delta_1 is not calculated because we do not associate error with the input  
          %     
          %     % CAPITAL delta update
          %     Theta1_grad = Theta1_grad + (delta2 * a1'); % 25 x 401
          %     Theta2_grad = Theta2_grad + (delta3 * a2'); % 10 x 26
          %  
          % end
          % 
          % Theta1_grad = (1/m) * Theta1_grad; % 25 x 401
          % Theta2_grad = (1/m) * Theta2_grad; % 10 x 26
          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
          %%%%%% WORKING: Backpropogation (Vectorized Implementation) %%%%%%%
          % Here X is including 1 column at begining
          A1 = X; % 5000 x 401
    
          Z2 = A1 * Theta1';  % m x hidden_layer_size == 5000 x 25
          A2 = sigmoid(Z2); % m x hidden_layer_size == 5000 x 25
          A2 = [ones(size(A2,1),1), A2]; % Adding 1 as first column in z = (Adding bias unit) % m x (hidden_layer_size + 1) == 5000 x 26
    
          Z3 = A2 * Theta2';  % m x num_labels == 5000 x 10
          A3 = sigmoid(Z3); % m x num_labels == 5000 x 10
    
          DELTA3 = A3 - y; % 5000 x 10
          DELTA2 = (DELTA3 * Theta2) .* [ones(size(Z2,1),1) sigmoidGradient(Z2)]; % 5000 x 26
          DELTA2 = DELTA2(:,2:end); % 5000 x 25 %Removing delta2 for bias node
    
          Theta1_grad = (1/m) * (DELTA2' * A1); % 25 x 401
          Theta2_grad = (1/m) * (DELTA3' * A2); % 10 x 26
    
          %%%%%%%%%%%% WORKING: DIRECT CALCULATION OF THETA GRADIENT WITH REGULARISATION %%%%%%%%%%%
          % %Regularization term is later added in Part 3
          % Theta1_grad = (1/m) * Theta1_grad + (lambda/m) * [zeros(size(Theta1, 1), 1) Theta1(:,2:end)]; % 25 x 401
          % Theta2_grad = (1/m) * Theta2_grad + (lambda/m) * [zeros(size(Theta2, 1), 1) Theta2(:,2:end)]; % 10 x 26
          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    
          %%%%%%%%%%%% Part 3: Adding Regularisation term in J and Theta_grad %%%%%%%%%%%%%
          reg_term = (lambda/(2*m)) * (sum(sum(Theta1(:,2:end).^2)) + sum(sum(Theta2(:,2:end).^2))); %scalar
    
          %Costfunction With regularization
          J = J + reg_term; %scalar
    
          %Calculating gradients for the regularization
          Theta1_grad_reg_term = (lambda/m) * [zeros(size(Theta1, 1), 1) Theta1(:,2:end)]; % 25 x 401
          Theta2_grad_reg_term = (lambda/m) * [zeros(size(Theta2, 1), 1) Theta2(:,2:end)]; % 10 x 26
    
          %Adding regularization term to earlier calculated Theta_grad
          Theta1_grad = Theta1_grad + Theta1_grad_reg_term;
          Theta2_grad = Theta2_grad + Theta2_grad_reg_term;
    
          % -------------------------------------------------------------
    
          % =========================================================================
    
          % Unroll gradients
          grad = [Theta1_grad(:) ; Theta2_grad(:)];
    
        end
      

    Неделя 6. Советы по применению Машинного Обучения.



  • Решение заданий на Python от John Wittenauer и StevenPZChan.
  • Репозиторий c примерами данного курса от Oleksii Trekhleb.