%% Deep Dream Images Using GoogLeNet
% This example shows how to generate images using deepDreamImage with the pretrained convolutional neural network GoogLeNet.
% Deep Dream is a feature visualization technique in deep learning that synthesizes images that strongly activate network layers. By visualizing these images, you can highlight the image features learned by a network. These images are useful for understanding and diagnosing network behavior.
% You can generate interesting images by visualizing the features of the layers towards the end of the network.
% The example uses Deep Learning Toolbox™ and Deep Learning Toolbox Model for GoogLeNet Network to generate the images.
%% Load Pretrained Network
% Load a pretrained GoogLeNet Network. If the Deep Learning Toolbox Model for GoogLeNet Network support package is not installed, then the software provides a download link.

net = googlenet;

%
%% Generate Image
% To produce images that resemble a given class the most closely, select the fully connected layer. First, locate the layer index of this layer by viewing the network architecture using analyzeNetwork.

analyzeNetwork(net)

%
% Then select the fully connected layer, in this example, 142.

layer = 142;
layerName = net.Layers(layer).Name

% You can generate multiple images at once by selecting multiple classes. Select the classes you want to visualize by setting channels to be the indices of those class names.

channels = [114 293 341 484 563 950];

% The classes are stored in the Classes property of the output layer (the last layer). You can view the names of the selected classes by selecting the entries in channels.

net.Layers(end).Classes(channels)

% Generate the images using deepDreamImage. This command uses a compatible GPU, if available. Otherwise it uses the CPU. A CUDA® enabled NVIDIA® GPU with compute capability 3.0 or higher is required for running on a GPU.

I = deepDreamImage(net,layerName,channels);

% Display all the images together using imtile.

figure
I = imtile(I);
imshow(I)

%
%% Generate More Detailed Images
% Increasing the number of pyramid levels and iterations per pyramid level can produce more detailed images at the expense of additional computation.
% You can increase the number of iterations using the 'NumIterations' option. Set the number of iterations to 100.

iterations = 100;

% Generate a detailed image that strongly activates the 'tiger' class (channel 293). Set 'Verbose' to false to suppress detailed information on the optimization process.

channels = 293;
I = deepDreamImage(net,layerName,channels, ...
    'Verbose',false, ...
    'NumIterations',iterations);

figure
imshow(I)

% To produce larger and more detailed output images, you can increase both the number of pyramid levels and iterations per pyramid level.
% Set the number of pyramid levels to 4.

levels = 4;

% Generate a detailed image that strongly activates the 'castle' class (channel 484).

channels = 484;

I = deepDreamImage(net,layerName,channels, ...
    'Verbose',false, ...
    'NumIterations',iterations, ...
    'PyramidLevels',levels);

figure
imshow(I)

% Copyright 2019 The MathWorks, Inc.