matlab底层代码可视化高斯分布

  • 2019-01-12
  • 514
  • 0

为了回顾忘的差不多的matlab,使用底层代码实现一些界面功能。随便可视化下一元和多元高斯分布。(加深机器学习中 吴恩达 – 15.7的多元高斯分布 的印象 )

为什么不用GUIDE实现界面?虽然GUIDE做界面简单、好用,但即便界面多么简单、其生成的程序都会有两个文件,一个界面文件fig一个逻辑文件m,界面与逻辑分离在这些简单的小程序里面优势并不大,所以我还是倾向使用底层代码,它可以只使用一个m文件完成界面与逻辑。


1. 可视化一元高斯分布:

中文wiki:一元高斯分布

MATLAB 底层代码可视化一元高斯分布:

function [] = UnivarGaussianDistribution()
% Plot Univariate Gaussian distribution

% Parameter
[x_min, x_max] = deal(-2, 10);
[sigma_min, sigma_max] = deal(-2, 10);
[mu_min, mu_max] = deal(-2, 10);


% Create data
x = linspace(x_min, x_max, 1000);
global sigma mu
% Default sigma, mu is average of maximum and minimum.
sigma = (sigma_min + sigma_max) / 2;
mu = (mu_min + mu_max) / 2;

% Now create the other GUI
% position: [x, y, width, height]
S.fh = figure('units','pixels',...
              'position',[500 300 600 500],...
              'menubar','none',...
              'name','GaussianDistributionVisulization-Univariate ',...
              'numbertitle','off',...
              'resize','off');
% axes
ha = axes('Parent', S.fh, ...
    'Units', 'pixels', ...
    'Position', [50 120 500 320]);
% plot data
line = plot(x, gaussianfunc(x, mu, sigma), 'r', 'linewidth', 1);
xlim([x_min, x_max]); ylim([-0.5, 2.5]);
title('$y = f(x|\mu, \sigma) = \frac{1}{\sigma \sqrt{2\pi}}e^\frac{-(x - \mu)^2}{2 \sigma^2}$',...
    'Interpreter','latex', 'FontSize', 18)

% slider_1
S.tx(1) = uicontrol('style','text',...
                 'unit','pixel',...
                 'position',[150 10 40 20],...
                 'string','mu',...
                 'fontsize',10);
S.sl(1) = uicontrol('style','slide',...
                 'unit','pixel',...
                 'position',[200 10 200 20],...
                 'min', mu_min, 'value', mu,'max', mu_max);
S.ed(1) = uicontrol('style','edit',...
                    'unit','pixel',...
                    'position',[410 10 40 20],...
                    'fontsize',10,...
                    'string',num2str(mu));  % Displays the value.
% slider_2
S.tx(2) = uicontrol('style','text',...
                 'unit','pixel',...
                 'position',[150 50 40 20],...
                 'string','sigma',...
                 'fontsize',10);
S.sl(2) = uicontrol('style','slide',...
                 'unit','pixel',...
                 'position',[200 50 200 20],...
                 'min', sigma_min, 'value', sigma, 'max', sigma_max);
S.ed(2) = uicontrol('style','edit',...
                    'unit','pixel',...
                    'position',[410 50 40 20],...
                    'fontsize',10,...
                    'string',num2str(sigma));  % Displays the value.
set([S.sl(:);S.ed(:)],'call',{@h_call, S, line, x});
% shared Callback.
end

function gaus_y = gaussianfunc(x, mu, sigma)
gaus_y = 1/(sqrt(2*pi) * sigma) * exp(-(x - mu).^2 / (2 * sigma.^2));
end

function [] = h_call(varargin)
% Callback for the slider.
[h, ~, S, line, x] = deal(varargin{:});  % Get the calling handle and structure.
global sigma mu

switch h  % Who called?
    case S.sl(1)
        mu = get(S.sl(1),'val');
        set(S.ed(1),'string', mu) % Set edit to current slider.
    case S.sl(2)
        sigma = get(S.sl(2),'val');
        set(S.ed(2),'string', sigma) % Set edit to current slider.
    case S.ed(1)
        E = str2double(get(S.ed(1),'string'));  % Numerical edit string.
        SL1 = get(S.sl(1),{'min','value','max'});  % Get the slider's info.
        if E >= SL1{1} && E <= SL1{3}
            mu = E;
            set(S.sl(1),'value',E)  % E falls within range of slider.
        else
            set(S.ed(1),'string',SL1{2}) % User tried to set slider out of range. 
        end
    case S.ed(2)
        E = str2double(get(S.ed(2),'string'));  % Numerical edit string.
        SL2 = get(S.sl(2),{'min','value','max'});  % Get the slider's info.
        if E >= SL2{1} && E <= SL2{3}
            sigma = E;
            set(S.sl(2),'value',E)  % E falls within range of slider.
        else
            set(S.ed(2),'string',SL2{2}) % User tried to set slider out of range. 
        end
end
gaus_y = gaussianfunc(x, mu, sigma);
set(line, 'ydata', gaus_y);
end

运行样图:

1547796992980

滑动 slider 减小 sigma

1547797030340

增大 mu

1547797055743

2. 可视化多元高斯分布

中文wiki:多元高斯分布

function [] = MultiGaussianDistribution()
% Plot Multivariate Gaussian distribution

close

% Create data
[xy_min, xy_max] = deal(-2, 10);
var_range = 5;  % mu, Sigma range +/-5

global Sigma mu line tog_value z_shaped
mu = [1, 3];
Sigma = [1, 0; 0, 4];
% Sigma must be a square, symmetric, positive definite matrix.
tog_value = 1;

[mu_min, mu_max] = deal(mu - var_range, mu + var_range);
[Sigma_min, Sigma_max] = deal(Sigma - var_range, Sigma + var_range);

[x, y] = meshgrid(linspace(xy_min, xy_max, 100),linspace(xy_min, xy_max, 100));
X = [x(:) y(:)];
z = mvnpdf(X, mu, Sigma);
z_shaped = reshape(z, 100, 100);

% Now create the other GUI
% position: [x, y, width, height]
fg = figure('units','pixels',...
    'position',[500 200 665 500],...
    'name','GaussianDistributionVisulization-Multivariate ',...
    'numbertitle','off',...
    'resize','off');
% axes
S.ax = axes('Parent', fg, ...
    'Units', 'pixels', ...
    'Position', [100 120 500 320]);
% plot data
line = surf(x, y, z_shaped,...
    'edgecolor', 'interp');
xlim([xy_min, xy_max]); ylim([xy_min, xy_max]);
latex_text = ['$${f_x(x_1,\ldots ,x_k)={\frac {1}{\sqrt {(2\pi)^k|{',...
    '\Sigma}|}}} \exp \left(-{\frac {1}{2}}({{X} }-{{\mu }})^{{T}',...
    ' }{{\Sigma }}^{-1}({{X} }-{{\mu }})\right)}$$'];
title(latex_text,...
    'Interpreter', 'latex', 'FontSize', 12);
xlim([xy_min, xy_max]);ylim([xy_min, xy_max]);zlim([-0.02, 0.09]);
xlabel('x'); ylabel('y');
%% check box for surf or contourf
S.togbtn = uicontrol('style', 'togglebutton',...
    'unit', 'pixel',...
    'position', [20, 450, 50, 30],...
    'string', 'surf',...
    'val', tog_value,...
    'fontsize', 10,...
    'TooltipString', 'Switch figure style between 3-D surface and contour.');
%% slider 1-2: mu(1), mu(2)
position_mu = {[5 50 75 20], [80 50 140 20]; [5 10 75 20], [80 10 140 20]};
for ii = 1:2
    S.tx(ii) = uicontrol('style', 'text',...
        'unit', 'pixel',...
        'position', position_mu{ii, 1},...
        'string', sprintf('mu(%d): %d', ii, mu(ii)),...
        'fontsize', 10);
    S.sl(ii) = uicontrol('style', 'slide',...
        'unit', 'pixel',...
        'position', position_mu{ii, 2},...
        'min', mu_min(ii), 'value', mu(ii),'max', mu_max(ii));
end
%% slider 3-6: Sigma(1, 1)-Sigma(2, 2)
position_Sigma = {
    [225 40 75 40], [300 50 140 20];
    [225 0 75 40], [300 10 140 20];
    [445 40 75 40], [520 50 140 20];
    [445 0 75 40], [520 10 140 20];
    };
for ii = 1:4
    [row, column] = ind2sub(size(Sigma), ii);
    S.tx(ii + 2) = uicontrol('style', 'text',...
        'unit', 'pixel',...
        'position', position_Sigma{ii, 1},...
        'string', sprintf('Sigma(%d, %d): %d', row, column, Sigma(ii)),...
        'fontsize', 10);
    S.sl(ii + 2) = uicontrol('style', 'slide',...
        'unit', 'pixel',...
        'position', position_Sigma{ii, 2},...
        'min', Sigma_min(ii), 'value', Sigma(ii),'max', Sigma_max(ii));
end

set([S.togbtn; S.sl(:)],'call',{@h_call, S, X, x, y});  % shared Callback.
end

function [] = h_call(varargin)
% Callback for the slider.

[h, ~, S, X, x, y] = deal(varargin{:});  % Get the calling handle and structure.
global Sigma mu line tog_value z_shaped

switch h  % Who called?
    case S.togbtn
        tog_value = get(S.togbtn, 'value');  % Get toggle button's state
        if tog_value
            line = surf(x, y, reshape(z_shaped, 100, 100),...
                'edgecolor', 'interp');
            set(S.togbtn, 'string', 'surf');
        else
            line = contour(x, y, reshape(z_shaped, 100, 100),...
                'ShowText', 'on', 'LineWidth', 1);
            set(S.togbtn, 'string', 'contour');
        end
    case S.sl(1)
        mu(1) = get(S.sl(1),'val');  % Get slider's value.
        set(S.tx(1), 'string',['mu(1): ', num2str(mu(1))]);  % update text box.
    case S.sl(2)
        mu(2) = get(S.sl(2),'val');  % Get slider's value.
        set(S.tx(2), 'string',['mu(2): ', num2str(mu(2))]);  % update text box.
    case S.sl(3)
        Sigma(1) = get(S.sl(3),'val');  % Get slider's value.
        set(S.tx(3), 'string',['Sigma(1,1): ', num2str(Sigma(1))]);  % update text box.
    case S.sl(4)
        Sigma(2) = get(S.sl(4),'val');
        set(S.tx(4), 'string',['Sigma(2,1): ', num2str(Sigma(2))]);  % update text box.

        Sigma(3) = Sigma(2);  % make sure Sigma is symmetric matrix.
        set(S.sl(5), 'value', Sigma(2));  % Adjust the slider to match the value.
        set(S.tx(5), 'string',['Sigma(1,2): ', num2str(Sigma(2))]);
    case S.sl(5)
        Sigma(3) = get(S.sl(5),'val');
        set(S.tx(5), 'string',['Sigma(1,2): ', num2str(Sigma(3))]);  % update text box.

        Sigma(2) = Sigma(3);  % Make sure Sigma is symmetric matrix. 
        set(S.sl(4), 'value', Sigma(3));  % Adjust the slider to match the value.
        set(S.tx(4), 'string',['Sigma(2,1): ', num2str(Sigma(3))]);  % update text box.
    case S.sl(6)
        Sigma(4) = get(S.sl(6),'val');
        set(S.tx(6), 'string',['Sigma(2,2): ', num2str(Sigma(4))]);
end

try
    z_shaped = reshape(mvnpdf(X, mu, Sigma), 100, 100);  % if Sigma not square, symmetric, positive definite matrix.
    if tog_value
        %{
          I want to improve script performance. Casue I think update
        axes's zdata faster than plot a new axes.
        %}
%         line = surf(x, y, z_shaped,...  
%             'edgecolor', 'interp');
% %         line = surf(x, y, z_shaped,...
% %             'edgecolor', 'interp');
%         set(S.togbtn, 'string', 'surf');
        set(line, 'zdata', z_shaped)
    else
        h_contour = allchild(S.ax);
        set(h_contour, 'zdata', z_shaped)
        %{
          I want to improve script performance. Casue I think update
        axes's zdata faster than plot a new axes.
        %}
%         line = contour(x, y, z_shaped,...  % I want to improve script performance.
%             'ShowText', 'on', 'LineWidth', 1);
%         set(S.togbtn, 'string', 'contour');
    end
catch ME
    if (strcmp(ME.identifier, 'stats:mvnpdf:BadMatrixSigma'))
        disp('Incorrect Sigma: ');disp(Sigma);
        warndlg('Sigma must be a square, symmetric, positive definite matrix.')
    else
        errordlg(ME.message)
    end
end

end

图例:

1547470228995

1547470268141

点击左上角按钮切换成等势线-contour

1547470322261

1547470345381


版权声明: 本网站所有资源采用BY-NC-SA 4.0协议进行授权,转载应当以相同方式注明文章来自:matlab底层代码可视化高斯分布 - 一方的天地

评论

还没有任何评论,你来说两句吧

发表评论

陕ICP备18010914号
知识共享许可协议
本作品由一方天地采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资源请尽快联系站长,本站会在24h内删除有争议的资源。 -