%% Image Classification Using Transfer Learning
% This template function defines the training data, network architecture, and 
% training options for an image classification experiment using transfer learning. 
% Experiment Manager uses the outputs of this function to call the <matlab:doc('trainNetwork') 
% |trainNetwork|> function. For more information on transfer learning, see <matlab:helpview('deeplearning','ExpMgrTransferLearningExample') 
% Try Multiple Pretrained Networks for Transfer Learning>. For more information 
% on built-in experiments, see <matlab:helpview('deeplearning','exp-mgr-create-experiment') 
% Configure Built-in Training Experiment>.
% 
% Modify this function as a template to set up your own experiment.
%% Input
%% 
% * |params| is a structure with fields from the Experiment Manager hyperparameter 
% table.
%% Output
%% 
% * |augimdsTrain| is an |augmentedImageDatastore| object for the training data.
% * |layers| is a layer graph that defines the neural network architecture.
% * |options| is a |trainingOptions| object.
function [augimdsTrain,layers,options] = {functionName}(params)
%% Load Training Data
% Load the training data as an <matlab:doc('imageDatastore') |imageDatastore|> 
% from the collection of image data specified by |digitDatasetPath|. Call <matlab:doc('splitEachLabel') 
% |splitEachLabel|> to divide the data into training and validation data sets. 
% Call <matlab:doc('augmentedImageDatastore') |augmentedImageDatastore|> to create 
% augmented image data stores for the training and validation data.
digitDatasetPath = fullfile(matlabroot,'toolbox','nnet', ...
    'nndemos','nndatasets','DigitDataset');
imdsTrain = imageDatastore(digitDatasetPath, ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');
numTrainingFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imdsTrain,numTrainingFiles);
inputSize = [227 227 3];
augimdsTrain = augmentedImageDatastore(inputSize,imdsTrain, ...
    'ColorPreprocessing','gray2rgb');
augimdsValidation = augmentedImageDatastore(inputSize,imdsValidation, ...
    'ColorPreprocessing','gray2rgb');
%% 
% Replace the data with your own training and validation data. For more information, 
% see <matlab:helpview('deeplearning','data-sets-for-deep-learning') Data Sets 
% for Deep Learning>.
%% Define Network Architecture
% Define the convolutional neural network architecture in the layer graph |layers|.
numClasses = 10;
net = squeezenet;
layers = layerGraph(net);
learnableLayer = layers.Layers(64);
newLearnableLayer = convolution2dLayer(1,numClasses, ...
    'Name','new_conv', ...
    'WeightLearnRateFactor',10, ...
    'BiasLearnRateFactor',10);
layers = replaceLayer(layers,learnableLayer.Name,newLearnableLayer);
classLayer = layers.Layers(68);
newClassLayer = classificationLayer('Name','new_classoutput');
layers = replaceLayer(layers,classLayer.Name,newClassLayer);
%% 
% Replace the layer graph with your own layer graph to train. For more information, 
% see <matlab:helpview('deeplearning','list_of_layers') List of Deep Learning 
% Layers>.
%% Specify Training Options
% Call the <matlab:doc('trainingOptions') |trainingOptions|> function to specify 
% the training options for the experiment. Read the hyperparameters specified 
% in Experiment Manager by accessing the fields of the input |params|. For example, 
% access the initial learning rate |myInitialLearnRate| defined in the hyperparameter 
% table with the argument value |params.myInitialLearnRate|.
options = trainingOptions('sgdm', ...
    'MaxEpochs',5, ... 
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',30, ...
    'InitialLearnRate',params.myInitialLearnRate);
%% 
% End of experiment setup function.
end
%% 
% Copyright 2020-2021 The MathWorks, Inc.