����λ�ã���ҳ > �����̳� > �̳� > ����ѧϰ�������繹�����£�
����һƪ���¡�����ѧϰ�������繹�����ϣ��������������Բ㡢������Լ���ʧ������Ĺ�����ʽ�������н���һ���������繹����ʽ���������Ĵһ���򵥵ķ��������硣
����һƪ���¡� ����ѧϰ�������繹�����ϣ� �������������Բ㡢������Լ���ʧ������Ĺ�����ʽ�������н���һ���������繹����ʽ���������Ĵһ���򵥵ķ��������硣
�����������ʱ��������ṹ����һ������Ԫ��ɵģ���Щ�����������㡢���ز������㡣Ϊ��ʵ����һ�ṹ��ͨ����ʹ��������vector���������洢��Щ�㣬��Ϊ��������ǿɱ�ģ����ܸ��ݾ��������������仯��
��ʹ�������Ѿ�������Ԥѵ��������һ���IJ���������£������ض�������ͨ��������Ҫ����ģ��΢����������Ϊ��ͬ����������в�ͬ�����ݷֲ���Ҫ�����ѵ���ǹ���������������ģ�͵���Ҫ���衣
��ѵ�������У��������ؼ������
��ʧ���� ���������ѧϰĿ�꣬ͨ����С����ʧ�������Ż�ģ�Ͳ�����ѡ����ʵ���ʧ��������ȷ��ģ���ܹ�ѧϰ����Ч��������ʾ������Ҫ��
�Ż��� ���Ż����������ģ�͵IJ�������С����ʧ���������˻����IJ������¹����⣬�Ż����������ṩ���߼��Ĺ��ܣ���ѧϰ�ʵ����Ͳ������ᣬ��Щ�������������ѵ��Ч�ʺ�ģ�����ܡ�
���ݼ������� ��������ѵ����������Ч�ع������ṩ���ݣ��������ݵļ��ء�Ԥ����������������ȷ�����ݱ�������á�
����������ⲿ�ӿڣ����з���������Ҫ�����¼��ࣺ
�����Ǵ���ʾ����
class Network {
private:
vector> layers;
shared_ptr lossFunction;
shared_ptr optimizer;
shared_ptr datasetManager;
public:
void addLayer(shared_ptr layer);
void setLossFunction(shared_ptr lossFunc);
void setOptimizer(shared_ptr opt);
void setDatasetManager(shared_ptr manager);
MatrixXd forward(const MatrixXd& input);
void backward(const MatrixXd& outputGrad);
double train(size_t epochs, size_t batchSize);
};
ʹ��shared_ptr�ĺô���
�洢��ʽvector
�����ѵ������ͨ�������������������ѵ���ļ��������ߴ磺
����
epochs
��ָѵ�����������ĵ����Ĵ�������ÿһ��epoch�У������ʹ��ѵ�����е������������в������¡�
���ߴ�
batchSize
��ָ��һ�ε��������ڸ���ģ�Ͳ�����������������ÿ�ε����У�ģ�ͻ������Щ���������ݶȣ����ݴ˵���ģ�͵IJ�����
��ˣ������ѵ������������Ñ���ṹ��ɣ����Ñ���ṹ��ʾ���������Ĵ�����ֱ��������е���ʱֹͣ���ڲ�Ñ����ʾѵ�����������������ȡ�Ľ��ȣ�ֱ��ѵ�����е��������ݱ�����ʱֹͣ��
�����ѵ���������ɶ�εIJ������������£���ɵġ��������ĵĵ�����������Batch��Ϊ��λ�ġ�������˵��һ�ε����������²��裺
����������£�
double Network::train(size_t epochs, size_t batchSize) {
double totalLoss = 0.0;
size_t sampleCount = datasetManager->getTrainSampleCount();
for (size_t epoch = 0; epoch < epochs; ++epoch) {
datasetManager->shuffleTrainSet();
totalLoss = 0.0;
for (size_t i = 0; i < sampleCount; i += batchSize) {
// ��ȡһ��С��������
auto batch = datasetManager->getTrainBatch(batchSize, i / batchSize);
MatrixXd batchInput = batch.first;
MatrixXd batchLabel = batch.second;
// ǰ�򴫲�
MatrixXd predicted = forward(batchInput);
double loss = lossFunction->computeLoss(predicted, batchLabel);
// ���򴫲�
MatrixXd outputGrad = lossFunction->computeGradient(predicted, batchLabel);
backward(outputGrad);
// ��������
optimizer->update(layers);
// �ۼ���ʧ
totalLoss += loss;
}
totalLoss /= datasetManager->getTrainSampleCount();
// ���ÿ��epoch����ʧ����Ϣ
std::cout << "Epoch " << epoch << ", totalLoss = " << totalLoss << "\n";
}
return totalLoss / (epochs * (sampleCount / batchSize)); // ����ƽ����ʧ����ʾ����
}
����Ĵ��������������������з����Ĵ���ʵ�֣�
void Network::addLayer(std::shared_ptr layer) {
layers.push_back(layer);
}
void Network::setLossFunction(std::shared_ptr lossFunc) {
lossFunction = lossFunc;
}
void Network::setOptimizer(std::shared_ptr opt) {
optimizer = opt;
}
void Network::setDatasetManager(std::shared_ptr manager) {
datasetManager = manager;
}
MatrixXd Network::forward(const MatrixXd& input) {
MatrixXd currentInput = input;
for (const auto& layer : layers) {
currentInput = layer->forward(currentInput);
}
return currentInput;
}
void Network::backward(const MatrixXd& outputGrad) {
MatrixXd currentGrad = outputGrad;
for (auto it = layers.rbegin(); it != layers.rend(); ++it) {
currentGrad = (*it)->backward(currentGrad);
}
}
forward
����������Ϊѵ��ʱ�IJ���֮һ����������������������Ԥ�⣩���������Ϊ���з���
backward
����ֻ��ѵ��ʱʹ�ã���������ʹ����;�У����ᱻ�ⲿ���ã���ˣ����������Ϊ˽�з�����
���ݼ�����������Ŀ���������������ݵ������ʣ�����Ҫְ���У�
class DatasetManager {
private:
MatrixXd input;
MatrixXd label;
std::vector trainIndices;
std::vector valIndices;
std::vector testIndices;
public:
// �������ݼ��ķ���
void setDataset(const MatrixXd& inputData, const MatrixXd& labelData);
// �������ݼ�Ϊѵ��������֤���Ͳ��Լ�
void splitDataset(double trainRatio = 0.8, double valRatio = 0.1, double testRatio = 0.1);
// ��ȡѵ��������֤���Ͳ��Լ���С��������
std::pair getBatch(std::vector& indices, size_t batchSize, size_t offset = 0);
// �������ѵ����
void shuffleTrainSet();
// ��ȡ��������
std::pair getTrainBatch(size_t batchSize, size_t offset = 0);
std::pair getValidationBatch(size_t batchSize, size_t offset = 0);
std::pair getTestBatch(size_t batchSize, size_t offset = 0);
// ��ȡ���������ķ���
size_t getSampleCount() const;
size_t getTrainSampleCount() const;
size_t getValidationSampleCount() const;
size_t getTestSampleCount() const;
};
���ݼ���ʼ����Ϊ���������ݼ����á����ݼ����֡����ݼ����ҡ�
// �������ݼ�
void ML::DatasetManager::setDataset(const MatrixXd& inputData, const MatrixXd& labelData) {
input = inputData;
label = labelData;
trainIndices.resize(input.rows());
std::iota(trainIndices.begin(), trainIndices.end(), 0);
valIndices.clear();
testIndices.clear();
}
// ����ѵ����
void ML::DatasetManager::shuffleTrainSet() {
std::shuffle(trainIndices.begin(), trainIndices.end(), std::mt19937{ std::random_device{}() });
}
// �������ݼ�Ϊѵ��������֤���Ͳ��Լ�
void ML::DatasetManager::splitDataset(double trainRatio, double valRatio, double testRatio) {
size_t totalSamples = input.rows();
size_t trainSize = static_cast(totalSamples * trainRatio);
size_t valSize = static_cast(totalSamples * valRatio);
size_t testSize = totalSamples - trainSize - valSize;
shuffleTrainSet();
valIndices.assign(trainIndices.begin() + trainSize, trainIndices.begin() + trainSize + valSize);
testIndices.assign(trainIndices.begin() + trainSize + valSize, trainIndices.end());
trainIndices.resize(trainSize);
}
���ڴ��Ҳ�����Ƶ���ij��������������Ǹ�Ϊ��Ч�IJ����������ڲ��������ҵij�����ֱ�������ݼ��ϴ��Ҹ�Ϊ��Ч�������н��������������Ĵ���ʾ����
�ڻ�ȡ����ʱ��������ȷ�������ݼ������ͣ�ѵ��������֤������Ȼ�󣬸���Ԥ������δ�С��Batchsize�����������б�����ȡ��Ӧ������������������Щ������Ӧ�����ݴ洢����ʱ�����С���󣬵������ݣ���ɶ�ȡ������
// ��ȡѵ��������֤���Ͳ��Լ���С��������
std::pair ML::DatasetManager::getBatch(std::vector& indices, size_t batchSize, size_t offset) {
size_t start = offset * batchSize;
size_t end = std::min(start + batchSize, indices.size());
MatrixXd batchInput = MatrixXd::Zero(end - start, input.cols());
MatrixXd batchLabel = MatrixXd::Zero(end - start, label.cols());
for (size_t i = start; i < end; ++i) {
batchInput.row(i - start) = input.row(indices[i]);
batchLabel.row(i - start) = label.row(indices[i]);
}
return std::make_pair(batchInput, batchLabel);
}
// ��ȡѵ��������������
std::pair ML::DatasetManager::getTrainBatch(size_t batchSize, size_t offset) {
return getBatch(trainIndices, batchSize, offset);
}
// ��ȡ��֤������������
std::pair ML::DatasetManager::getValidationBatch(size_t batchSize, size_t offset) {
return getBatch(valIndices, batchSize, offset);
}
// ��ȡ���Լ�����������
std::pair ML::DatasetManager::getTestBatch(size_t batchSize, size_t offset) {
return getBatch(testIndices, batchSize, offset);
}
Ϊ���ڴ��뿪������ҪΪ���ݼ�����������ⲿ�ӿڣ��Ա����ⲿ���Ի�ȡ�������ݼ��ijߴ硣
size_t ML::DatasetManager::getSampleCount() const {
return input.rows();
}
size_t ML::DatasetManager::getTrainSampleCount() const {
return trainIndices.size();
}
size_t ML::DatasetManager::getValidationSampleCount() const {
return valIndices.size();
}
size_t ML::DatasetManager::getTestSampleCount() const {
return testIndices.size();
}
����ݶ��½���һ���Ż��㷨��������С����ʧ������ѵ��ģ�Ͳ������������ݶ��½���Batch Gradient Descent����ͬ��SGD��ÿ�θ��²���ʱֻʹ��һ����������һ��С������������������������ѵ��������ʹ��SGD�ڼ����ϸ���Ч�����ܹ�������������������ڴ������ģ����ʱ������Ϊ����ݶ��½��Ĵ���ʾ����
class Optimizer {
public:
virtual void update(std::vector>& layers) = 0;
virtual ~Optimizer() {}
};
class SGDOptimizer : public Optimizer {
private:
double learningRate;
public:
SGDOptimizer(double learningRate) : learningRate(learningRate) {}
void update(std::vector>& layers) override;
};
void SGDOptimizer::update(std::vector>& layers) {
for (auto& layer : layers) {
layer->update(learningRate);
}
}
�����ϣ��������Щ���룬���ȿ��Դӱ�ƪ���£��Լ�
��һƪ����
�и��ƴ��룬���ο�����ͼƬ������Ľ��������
��������������⣬��Ó��ϵ���ߣ�
��������Ϊ���Իع�IJ���������
namespace LNR{
// linear_regression
void gen(MatrixXd& X, MatrixXd& y);
void test();
}
void LNR::gen(MatrixXd& X, MatrixXd& y) {
MatrixXd w(X.cols(), 1);
X.setRandom();
w.setRandom();
X.rowwise() -= X.colwise().mean();
X.array().rowwise() /= X.array().colwise().norm();
y = X * w;
}
void LNR::test() {
std::cout << std::fixed << std::setprecision(2);
size_t input_dim = 10;
size_t sample_num = 2000;
MatrixXd X(sample_num, input_dim);
MatrixXd y(sample_num, 1);
gen(X, y);
ML::DatasetManager dataset;
dataset.setDataset(X, y);
ML::Network net;
net.addLayer(std::make_shared(input_dim, 1));
net.setLossFunction(std::make_shared());
net.setOptimizer(std::make_shared(0.25));
net.setDatasetManager(std::make_shared(dataset));
size_t epochs = 600;
size_t batch_size = 50;
net.train(epochs, batch_size);
MatrixXd error(sample_num, 1);
error = net.forward(X) - y;
std::cout << "error=\n" << error << "\n";
}
��ϸ����
gen
�������������ɲ������ݡ�
���չʾ
���ѵ��������Ԥ��ֵ����ʵֵ���������ͼ�����׷��֣�������нϺõ�Ԥ�⾫�ȡ�
��������Ϊ�߼��ع�IJ���������
namespace LC {
// Linear classification
void gen(MatrixXd& X, MatrixXd& y);
void test();
}
void LC::gen(MatrixXd& X, MatrixXd& y) {
MatrixXd w(X.cols(), 1);
X.setRandom();
w.setRandom();
X.rowwise() -= X.colwise().mean();
X.array().rowwise() /= X.array().colwise().norm();
y = X * w;
y = y.unaryExpr([](double x) { return x > 0.0 ? 1.0 : 0.0; });
}
void LC::test() {
std::cout << std::fixed << std::setprecision(3);
size_t input_dim = 10;
size_t sample_num = 2000;
MatrixXd X(sample_num, input_dim);
MatrixXd y(sample_num, 1);
gen(X, y);
ML::DatasetManager dataset;
dataset.setDataset(X, y);
ML::Network net;
net.addLayer(std::make_shared(input_dim, 1));
net.addLayer(std::make_shared());
net.setLossFunction(std::make_shared());
net.setOptimizer(std::make_shared(0.05));
net.setDatasetManager(std::make_shared(dataset));
size_t epochs = 200;
size_t batch_size = 25;
net.train(epochs, batch_size);
MatrixXd predict(sample_num, 1);
predict = net.forward(X);
predict = predict.unaryExpr([](double x) { return x > 0.5 ? 1.0 : 0.0; });
MatrixXd error(sample_num, 1);
error = y - predict;
error = error.unaryExpr([](double x) {return (x < 0.01 && x>-0.01) ? 1.0 : 0.0; });
std::cout << "��ȷ��=\n" << error.sum() / sample_num << "\n";
}
��ϸ����
gen
�������������ɲ������ݡ�
���չʾ
��ͼ��ӳ������Ԥ������е���ʧ�仯�����Կ�����ʧ���½������ơ�
���ѵ������������Ԥ��������ȷ�ʡ����Է��֣�������нϺõ�Ԥ�⾫�ȡ�
ʹ��Blender���ɳ���ģ��
�Ķ�ȫ����������ERA5�����ط���
�Ķ�Xpath���������﷨
�Ķ�����ѧϰ�������繹�����£�
�Ķ���ΪMateƷ��ʢ�䣺HarmonyOS NEXT�ӳ�����Ϸ���ܵõ�����ͷ�
�Ķ�ʵ�ֶ��󼯺���DataTable���໥ת��
�Ķ�Ӳ�̵Ļ���֪ʶ��ѡ��ָ��
�Ķ�������й��ƶ��ı�ͼ��ײ�
�Ķ�����NEXTԪ�����������ѿ����ϼ���Ʒ
�Ķ��ᳲ���С������������Ƽ��رշ���
�Ķ������ArcMap�����н���դ��ͼ���ز�������
�Ķ��㷨�����ݽṹ 1 - ģ��
�Ķ���Ѷ�����߿ͷ���Ӫ��ϵͳ����
�Ķ���Ѷ��Ƶҹ��ģʽ���ý̳�
�Ķ����ں���NEXT��Ѫ���Ŵ���������������
�Ķ�5. Spring Cloud OpenFeign ����ʽ WebService �ͻ��˵ij���ϸʹ��
�Ķ�Java����ģʽ����̬�����Ͷ�̬�����ĶԱȷ���
�Ķ�Win11�ʼDZ����Զ�����Ӧ�õ���ɫ����ʾ����
�Ķ�˼�� V1.5.6 ��׿��
��ս�귨 V7.5.0 ��׿��
У��������������׵������� V1.0 ��׿��
��˸֮�� V1.9.7 ��׿��
������Ե����� v1.0.4 ��׿��
������֮ŠV5.2.3 ��׿��
��������������Դ V1.0 ��׿��
���֮Ϣ V1.0 ��׿��
��ħ������������䣩 V1.0 ��׿��
���ں�������ϵ�����������������վ�����������������Ƽ�����
Ƶ�� ����Ƶ��������ר������������׿�������app����
�Ƽ� ��Ô���������°��������ܿ������ز���
���� ����ɫ������������ ���������ս������������
ɨ��ά�����������ֻ��汾��
ɨ��ά����������΢�Ź��ںţ�
��վ�������������������ϴ��������ַ���İ�Ȩ���뷢�ʼ�[email protected]
��ICP��2022002427��-10 �湫��������43070202000427��© 2013~2025 haote.com ������