pcstyle

Untitled

Nov 6th, 2025
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 5.64 KB | None | 0 0
  1. function som_iris_ex4()
  2.     % SOM on IRIS for different final neighborhood sizes
  3.     % (port of your Python code to MATLAB)
  4.  
  5.     rng(7);  % reproducible random generator
  6.    
  7.     R = 12;
  8.     C = 12;          % bigger lattice
  9.     M = R * C;
  10.     iters = 4000;    % more iterations for bigger maps
  11.    
  12.     eta0 = 0.12;
  13.     sigma0 = max(R, C) / 2;       % initial neighborhood (global ordering)
  14.     sigma_final_list = [1 2 3];   % final sigmas to test
  15.    
  16.     % --- load and scale iris data (150x4, each feature to [0,1]) ---
  17.     load fisheriris   % variables: meas (150x4), species
  18.     X = meas;         % 150x4
  19.     S = size(X, 1);
  20.    
  21.     Xmin = min(X, [], 1);
  22.     Xmax = max(X, [], 1);
  23.     X    = (X - Xmin) ./ (Xmax - Xmin);   % min-max scaling to [0,1]
  24.    
  25.     fprintf('loaded iris: %d samples, %d features\n', S, size(X, 2));
  26.     fprintf('grid: %dx%d = %d neurons\n', R, C, M);
  27.     fprintf('testing sigma_final: [');
  28.     fprintf('%d ', sigma_final_list);
  29.     fprintf(']\n');
  30.    
  31.     % grid coordinates (same idea as Python meshgrid + ravel)
  32.     [gx, gy] = meshgrid(1:C, 1:R);   % gx,gy: R x C
  33.     grid2d   = [gx(:), gy(:)];       % M x 2
  34.    
  35.     % --- figure for topographic error ---
  36.     fig1 = figure('Color', 'w', 'Position', [100 100 800 500]);
  37.     ax1 = axes('Parent', fig1);
  38.     hold(ax1, 'on');
  39.     xlabel(ax1, 'Iteration');
  40.     ylabel(ax1, 'Topographic Error');
  41.     title(ax1, sprintf('R=%d, C=%d — Effect of final \\sigma in {1,2,3}', R, C));
  42.     grid(ax1, 'on');
  43.     box(ax1, 'on');
  44.    
  45.     results = struct('sigma_final', {}, 'W', {}, 'topoErr', {}, 'topoErr_s', {});
  46.    
  47.     tau = iters;   % single time constant for whole run
  48.    
  49.     for k = 1:numel(sigma_final_list)
  50.         sigma_final = sigma_final_list(k);
  51.         fprintf('\n=== Testing sigma_final = %d ===\n', sigma_final);
  52.        
  53.         % weights in [0,1], same scale as X
  54.         W = rand(M, size(X, 2));
  55.        
  56.         topoErr = zeros(iters, 1);
  57.        
  58.         for t = 1:iters
  59.             % --- time-dependent sigma and eta ---
  60.             sigma_t = sigma_final + (sigma0 - sigma_final) * exp(-t / tau);
  61.             eta_t   = eta0 * exp(-t / tau);
  62.            
  63.             % --- random sample from X ---
  64.             idx_sample = randi(S);
  65.             x = X(idx_sample, :);   % 1 x D
  66.            
  67.             % --- BMU1, BMU2 ---
  68.             dists = sum((W - x).^2, 2);  % M x 1
  69.             [~, idx_sorted] = sort(dists, 'ascend');
  70.             bmu1 = idx_sorted(1);
  71.             bmu2 = idx_sorted(2);
  72.            
  73.             % --- Gaussian neighborhood around BMU1 in grid space ---
  74.             dgrid2 = sum((grid2d - grid2d(bmu1, :)).^2, 2);  % M x 1
  75.             h = exp(-dgrid2 / (2 * sigma_t^2));
  76.             h = h / max(h);    % normalize
  77.            
  78.             % --- update weights ---
  79.             % implicit expansion: h (M x 1) with (x - W) (M x D)
  80.             W = W + eta_t * (h .* (x - W));
  81.            
  82.             % --- topographic error: 0 if BMU1,BMU2 are neighbors, else 1 ---
  83.             topoErr(t) = ~are_neighbors(grid2d, bmu1, bmu2);
  84.            
  85.             if mod(t, 1000) == 0
  86.                 fprintf('  iteration %d/%d, sigma=%.3f, eta=%.5f\n', ...
  87.                         t, iters, sigma_t, eta_t);
  88.             end
  89.         end
  90.        
  91.         % smoothing TE with moving average (okno = 50)
  92.         win = 50;
  93.         topoErr_s = movmean(topoErr, win);
  94.        
  95.         results(k).sigma_final = sigma_final;
  96.         results(k).W           = W;
  97.         results(k).topoErr     = topoErr;
  98.         results(k).topoErr_s   = topoErr_s;
  99.        
  100.         % plot TE curve
  101.         plot(ax1, 1:iters, topoErr_s, 'LineWidth', 1.5, ...
  102.              'DisplayName', sprintf('\\sigma_{final}=%d', sigma_final));
  103.     end
  104.    
  105.     legend(ax1, 'Location', 'northeast');
  106.    
  107.     % --- PCA projection and final lattices ---
  108.     fig2 = figure('Color', 'w', 'Position', [100 100 1200 350]);
  109.    
  110.     for k = 1:numel(results)
  111.         W = results(k).W;
  112.        
  113.         % PCA to 2D
  114.         [coeff, score] = pca(W); %#ok<ASGLU>
  115.         W2 = score(:, 1:2);   % M x 2
  116.        
  117.         WX = reshape(W2(:, 1), R, C);
  118.         WY = reshape(W2(:, 2), R, C);
  119.        
  120.         ax = subplot(1, numel(results), k, 'Parent', fig2);
  121.         hold(ax, 'on');
  122.         axis(ax, 'equal');
  123.         box(ax, 'on');
  124.         title(ax, sprintf('\\sigma_{final}=%d', results(k).sigma_final));
  125.        
  126.         % horizontal lines (rows)
  127.         for r = 1:R
  128.             plot(ax, WX(r, :), WY(r, :), '-', 'LineWidth', 1.0);
  129.         end
  130.        
  131.         % vertical lines (columns)
  132.         for c = 1:C
  133.             plot(ax, WX(:, c), WY(:, c), '-', 'LineWidth', 1.0);
  134.         end
  135.        
  136.         % neuron markers
  137.         plot(ax, W2(:, 1), W2(:, 2), 'ko', 'MarkerSize', 2, 'MarkerFaceColor', 'k');
  138.     end
  139.    
  140.     sgtitle('Final Lattices Projected by PCA');
  141.    
  142.     % --- summary ---
  143.     fprintf('\n== Summary (lower TE is better) ==\n');
  144.     for k = 1:numel(results)
  145.         topoErr = results(k).topoErr;
  146.         last500 = topoErr(end-499:end);
  147.         te_mean = mean(last500);
  148.         fprintf('sigma_final=%d -> mean TE (last 500 iters): %.4f\n', ...
  149.                 results(k).sigma_final, te_mean);
  150.     end
  151. end
  152.  
  153. % =======================================================================
  154. % local helpers
  155. % =======================================================================
  156.  
  157. function tf = are_neighbors(grid2d, i, j)
  158.     % odleglosc Chebyshev = 1 (8-neighborhood)
  159.     % grid2d: M x 2, i,j: indices of neurons
  160.     di = abs(grid2d(i,1) - grid2d(j,1));
  161.     dj = abs(grid2d(i,2) - grid2d(j,2));
  162.     tf = max(di, dj) == 1;   % true if neighbors
  163. end
Advertisement
Add Comment
Please, Sign In to add comment