%% CNN-RNN 通用分类：Iris 一维特征案例
clear; clc; close all;
fprintf('=== CNN-RNN通用分类试用版 ===\n');
fprintf('最多100条样本；最多两层卷积；隐藏单元不超过64；最多训练30轮\n');
fprintf('试用版开放LSTM和GRU，结果图带试用版水印\n');
fprintf('完整功能与持续更新：www.khsci.com/docs\n\n');

%% 1. 导入数据
% 前四列是花萼、花瓣的长度与宽度，最后一列是类别编号。
data = readmatrix('iris.csv');
X = data(:, 1:4);
Y = data(:, 5);

%% 2. 输入适配与数据划分
options.sampleDimension = 'auto'; % 自动识别第一维150为样本维。
options.sequenceAxis = 1;          % 单条样本只有一维，沿4个特征依次读取。
options.rTrain = 0.80;             % 80%先作为训练+验证数据，剩余20%为测试集。
options.validationRatio = 0.15;    % 从训练+验证数据中再取15%作为验证集。
options.shuffle = true;            % 独立样本采用分层随机划分。
options.seed = 42;                 % 固定划分和网络初始化。

%% 3. CNN-RNN 网络结构
options.networkType = 'LSTM';      % 试用版可选LSTM/GRU；BiLSTM在完整版开放。
options.convChannels = 16;         % 一层卷积输出16个局部特征通道。
options.kernelSize = 3;            % 一次观察3个相邻特征位置。
options.poolSize = 1;              % 序列仅长4，不使用池化。
options.rnnHidden = 24;            % LSTM隐藏单元数。
options.dropout = 0.10;            % 分类头前随机失活10%。

%% 4. 训练参数
options.solverName = 'adam';       % 使用Adam优化器。
options.maxEpochs = 30;            % 试用版最多30轮，可能因早停提前结束。
options.learnRate = 0.003;         % Iris小数据使用稍大的初始学习率。
options.batchSize = 16;            % 每批16条样本。
options.earlyStoppingPatience = 15;% 验证损失连续15次不改善则停止。
options.learnRateSchedule = 'none';% 本案例保持学习率不变。
options.learnRateDropPeriod = 15;  % schedule为none时不生效。
options.learnRateDropFactor = 0.5; % schedule为none时不生效。
options.classWeight = 'auto';      % 根据训练集类别数量自动计算权重。
options.executionEnvironment = 'auto'; % 自动选择GPU或CPU。

%% 5. 数据处理与图像输出
options.mapflag = 'on';            % on标准化；参数仅由训练集计算，off关闭。
options.figflag = 'on';            % on自动生成并保存五张图，off关闭绘图。
options.showFigures = 'on';        % on运行时弹出图窗；图片同时保存。
options.caseName = 'Iris';         % 图片文件名前缀。
options.classNames = {'山鸢尾','变色鸢尾','维吉尼亚鸢尾'};

%% 6. 核心函数入口与输出说明
% X：样本数×特征长度的有限数值数组；Y：每条样本的类别标签。
% options：逐项控制样本维、序列轴、三集合划分、网络、训练、标准化和绘图。
% 试用版最多输入100条，超限直接停止，不会偷偷截断。
% foreData/foreDataTrain：测试集/训练集预测；net：训练后的网络。
% info：三集合索引与指标、验证预测、类别得分、训练记录、标准化和尺寸信息。
[foreData, foreDataTrain, net, info] = FunClassCNNRNN(X, Y, options);
