function [imds,layers,options] = {functionName}(params)
%% Set up an Experiment to Train a Neural Network
% This template function constructs an image data store as a training data set, 
% a layer graph, and training options. Outputs of this setup function are used 
% to call the <matlab:doc('trainNetwork') |trainNetwork|> function. For more information, 
% see <matlab:helpview('deeplearning','exp-mgr-create-experiment') Configure Deep 
% Learning Experiment>.
% 
% Modify this function as a template to set up your own experiment. 
% 
%% Input
% * |params| is a struct with fields from the Experiment Manager hyperparameter table.
% 
%% Output
% * |imds| is a data store for the training data.
% * |layers| is a layer graph that defines the neural network architecture.
% * |options| is a training options object.


%% Load Image Data
% Load the sample data as an image datastore |imds| from the collection of image 
% data specified by |digitDatasetPath|. For more information, see <matlab:doc('imageDatastore') |imageDatastore|>.
% Call <matlab:doc('splitEachLabel') |splitEachLabel|> to divide the data into 
% training and validation data sets.

digitDatasetPath = fullfile(matlabroot,'toolbox','nnet', ...
    'nndemos','nndatasets','DigitDataset');
imds = imageDatastore(digitDatasetPath, ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

numTrainingFiles = 750;
[imds,imdsValidation] = splitEachLabel(imds,numTrainingFiles);

%%
% Replace 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. 
% For more information, see <matlab:helpview('deeplearning','list_of_layers') 
% List of Deep Learning Layers>.
inputSize = [28 28 1];
numClasses = 10;
layers = [
    imageInputLayer(inputSize)
    convolution2dLayer(5,20)
    batchNormalizationLayer
    reluLayer
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];

%% 
% Replace with your own layer graph to train. For example, for transfer learning  
% using <matlab:doc('googlenet') |googlenet|>, uncomment this code:

% numClasses = numel(categories(imds.Labels));
% imds = augmentedImageDatastore([224 224],imds, ... 
%             'ColorPreprocessing','gray2rgb'); 
% imdsValidation = augmentedImageDatastore([224 224],imdsValidation, ... 
%             'ColorPreprocessing','gray2rgb');
% net = googlenet;
% layers = layerGraph(net);
% newLearnableLayer = fullyConnectedLayer(numClasses, ...
%        'Name','new_fc', ...
%        'WeightLearnRateFactor',10, ...
%        'BiasLearnRateFactor',10);
% layers = replaceLayer(layers,'loss3-classifier',newLearnableLayer);
% newClassLayer = classificationLayer('Name','new_classoutput');
% layers = replaceLayer(layers,'output',newClassLayer);

%% Specify Training Options
% To use the hyperparameters specified in the Experiment Manager,
% access fields of the struct |params| by using dot notation.
% For example, to use the initial learn rate |myInitialLearnRate|
% defined in the hyperparameter table, call the <matlab:doc('trainingOptions') |trainingOptions|>
% function with the argument value |params.myInitialLearnRate|.

options = trainingOptions('sgdm', ...
    'MaxEpochs',5, ... 
    'ValidationData',imdsValidation, ...
    'ValidationFrequency',30, ...
    'InitialLearnRate',params.myInitialLearnRate);

%%
% End of experiment setup function.
end
