%% TEST 2: MLP Z PODZIAŁEM NA ZBIORY (TRAIN, VALIDATION, TEST) – ZBIÓR IONOSPHERE % W tym skrypcie trenujemy sieć neuronową typu MLP (Multi-Layer Perceptron) % na zbiorze danych IONOSPHERE. Zbiór zawiera pomiary sygnałów radarowych % (X) i etykietę (Y) określającą, czy sygnał jest "good" (g) czy "bad" (b). % Sieć dokona binarnej klasyfikacji. Dodatkowo wykorzystujemy walidację (20%). % WYMAGANE TOOLBOXY: % - Deep Learning Toolbox % - Statistics and Machine Learning Toolbox (dla wczytania 'ionosphere.mat') % - Parallel Computing Toolbox (jeśli chcemy wykorzystywać GPU) %% 1. Przygotowanie danych rng('default'); % Ustawiamy generator liczb losowych (dla powtarzalności wyników) % Wczytanie danych Ionosphere: % Plik 'ionosphere.mat' zawiera zmienne: % X (351x34) -> cechy (numeryczne) % Y (351x1) -> etykiety 'g' / 'b' load ionosphere % Dla pewności zmieńmy etykiety na typ categorical: if ~iscategorical(Y) Y = categorical(Y); end n = size(X,1); % Liczba próbek (351) idx = randperm(n); % Losowo permutujemy indeksy 1..351 % Ustalamy proporcje zbiorów: 60% (train), 20% (val), 20% (test) trainRatio = 0.6; valRatio = 0.2; testRatio = 0.2; % Suma = 1.0 nTrain = round(trainRatio * n); nVal = round(valRatio * n); % Pozostałe ~ 20% pójdzie do testu % Wyznaczamy indeksy do train, val, test z losowej permutacji idx trainIdx = idx(1 : nTrain); valIdx = idx(nTrain+1 : nTrain + nVal); testIdx = idx(nTrain + nVal + 1 : end); % Przygotowujemy zbiory XTrain, YTrain, XVal, YVal, XTest, YTest XTrain = X(trainIdx, :); YTrain = Y(trainIdx, :); XVal = X(valIdx, :); YVal = Y(valIdx, :); XTest = X(testIdx, :); YTest = Y(testIdx, :); %% 2. Definicja architektury sieci MLP % Tu: MLP do binarnej klasyfikacji (ale warstwa wyjściowa będzie miała % liczbę neuronów = 2, a w MATLAB i tak dopasuje to do 2 klas: 'g' i 'b'). inputSize = size(X,2); % 34 cechy numClasses = 2; % 2 klasy (g / b) layers = [ featureInputLayer(inputSize,'Name','input') % warstwa wejściowa fullyConnectedLayer(10,'Name','fc1') % warstwa w pełni połączona (10 neuronów) reluLayer('Name','relu1') % funkcja aktywacji ReLU fullyConnectedLayer(numClasses,'Name','fc2') % warstwa w pełni połączona (2 neurony = 2 klasy) softmaxLayer('Name','softmax') % warstwa softmax (rozkład prawd.) classificationLayer('Name','classOutput') % warstwa klasyfikująca ]; %% 3. Ustawienie opcji treningu z walidacją % Ustawiamy parametry trenowania (optymalizator 'adam', 50 epok, walidacja, itp.) options = trainingOptions('adam', ... 'MaxEpochs', 50, ... 'MiniBatchSize', 16, ... 'ExecutionEnvironment','gpu', ... % ewentualnie 'auto', jeśli GPU nie jest dostępne 'InitialLearnRate', 0.01, ... 'ValidationData', {XVal, YVal}, ... % zbiór walidacyjny (20%) 'ValidationFrequency', 5, ... 'Plots','training-progress', ... 'Verbose',false); %% 4. Trenowanie sieci net = trainNetwork(XTrain, YTrain, layers, options); %% 5. Ocena na zbiorze testowym % Predykcja etykiet na XTest YPred = classify(net, XTest); % Dokładność klasyfikacji accuracy = mean(YPred == YTest); disp("Dokładność (accuracy) na zbiorze testowym: " + accuracy); % Rysujemy macierz pomyłek (confusion matrix) figure; plotconfusion(YTest, YPred); title('Macierz pomyłek: Sieć MLP (IONOSPHERE) - Zbiór Testowy'); %% (Opcjonalnie) 6. Tabela z porównaniem wyjść % Tworzymy tabelę (cechy + etykieta rzeczywista + etykieta przewidywana) % Uwaga: W Ionosphere mamy 34 cechy, można wypisać tylko pierwsze kilka dla czytelności nDispCech = 20; % np. pierwszych 5 cech comparisonTable = array2table(XTest(:,1:nDispCech), ... 'VariableNames', compose("Cecha%d", 1:nDispCech)); comparisonTable.RealLabel = cellstr(YTest); comparisonTable.PredictedLabel = cellstr(YPred); disp("TABELA: Porównanie etykiet rzeczywistych i przewidywanych (zbiór testowy)"); disp(comparisonTable); %% Wykres 3D punktów (cechy 3, 4 i 5) – nakładanie danych uczących i testowych % Obliczamy predykcje dla zbioru treningowego i testowego YPredTrain = classify(net, XTrain); YPredTest = classify(net, XTest); % Określamy, które próbki zostały poprawnie sklasyfikowane idxTrainCorrect = (YPredTrain == YTrain); idxTrainIncorrect = ~idxTrainCorrect; idxTestCorrect = (YPredTest == YTest); idxTestIncorrect = ~idxTestCorrect; % Tworzymy wykres 3D figure; hold on; title('Wykres 3D: Dane uczące i testowe (cechy 3,4,5)'); xlabel('Cecha 3'); ylabel('Cecha 4'); zlabel('Cecha 5'); % --- Dane uczące --- % Rysujemy dane uczące markerami "o" (okręgi): % Poprawnie sklasyfikowane dane uczące – zielone, wypełnione scatter3(XTrain(idxTrainCorrect,3), XTrain(idxTrainCorrect,4), XTrain(idxTrainCorrect,5), ... 50, 'g', 'o', 'filled', 'DisplayName', 'Train Correct'); % Błędnie sklasyfikowane dane uczące – czerwone, okręgi bez wypełnienia scatter3(XTrain(idxTrainIncorrect,3), XTrain(idxTrainIncorrect,4), XTrain(idxTrainIncorrect,5), ... 50, 'r', 'o', 'DisplayName', 'Train Incorrect'); % --- Dane testowe --- % Rysujemy dane testowe markerami "s" (kwadraty): % Poprawne predykcje – zielone, wypełnione scatter3(XTest(idxTestCorrect,3), XTest(idxTestCorrect,4), XTest(idxTestCorrect,5), ... 80, 'b', 's', 'filled', 'DisplayName', 'Test Correct'); % Błędne predykcje – czerwone, kwadraty bez wypełnienia scatter3(XTest(idxTestIncorrect,3), XTest(idxTestIncorrect,4), XTest(idxTestIncorrect,5), ... 80, 'k', 's', 'DisplayName', 'Test Incorrect'); grid on; legend('Location','best'); hold off;