惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
P
Privacy & Cybersecurity Law Blog
Cisco Talos Blog
Cisco Talos Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 叶小钗
爱范儿
爱范儿
C
CERT Recently Published Vulnerability Notes
Hugging Face - Blog
Hugging Face - Blog
P
Proofpoint News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Know Your Adversary
Know Your Adversary
Latest news
Latest news
T
Tor Project blog
NISL@THU
NISL@THU
The Hacker News
The Hacker News
IT之家
IT之家
Last Week in AI
Last Week in AI
T
Tenable Blog
C
Cybersecurity and Infrastructure Security Agency CISA
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Visual Studio Blog
Apple Machine Learning Research
Apple Machine Learning Research
T
Threat Research - Cisco Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
博客园 - 三生石上(FineUI控件)
Spread Privacy
Spread Privacy
S
Secure Thoughts
博客园 - 司徒正美
A
About on SuperTechFans
Attack and Defense Labs
Attack and Defense Labs
Microsoft Security Blog
Microsoft Security Blog
N
News and Events Feed by Topic
O
OpenAI News
V
V2EX
aimingoo的专栏
aimingoo的专栏
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Security Affairs
MyScale Blog
MyScale Blog
S
Schneier on Security
宝玉的分享
宝玉的分享
Hacker News - Newest:
Hacker News - Newest: "LLM"
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

洛屿的小站

STM32 UCOS3+HAL库集成中的FPU HardFault问题 一种简单的卡尔曼滤波器设计 Cadence - 应律而动,落指成音 Zephyr - 聆风之息,为你而奏 不改一行插件代码,实现消息优先级与阻断 洛玖定时任务系统 在 butterfly 主题中添加首页点集动画(基于p2line项目) 你好,2026 stm32f4xx-ads1256驱动 stm32f4xx-ad9854并行驱动 主动式网站状态监测实现及其应用 右键菜单加入用Trae打开文件和文件夹 三角洲行动ID映射表 洛玖SDK说明 为网页文章开头添加原文连接 Hexo-Butterfly主题在主页添加GitHub贡献日历 Proteus中555定时器仿真问题 装饰器 洛玖开发日记 STS3032舵机获取力矩输出 kotlin网页前后端那些事 mspm0g3507-ad9850 奇怪的bug Paddle模型转PaddleLite 人工智能考核 构建一个yolov3网络 yolo和paddle模型常见输出参数 PaddleDetection 随便写的一些东西 实验室C语言第一次考核题目讲解及相关代码解读 C语言神经网络房价预测系统 C、C++数组,指针,指针数组,数组指针的区别 C、C++的大括号是必须的部分吗? C、C++预处理详解 C、C++其他关键字详解 C、C++存储类型关键字详解 C、C++控制语句关键字详解 C、C++数据类型关键字详解 C、C++关键字 C++药品管理系统 Bi-LSTM(Attention)的PyTorch实现 easy库的使用 edgeboardFZ3A相关问题 Predict.py的编写 Paddle环境搭建 百度Paddle模型训练 GMD09601-0.96OLED显示屏 【LeetCode 1617】统计子树中城市之间最大距离 C语言学习相关 STM32阵列按键 CH32(F10X F20X) 最短路 拓扑排序
C语言实现波士顿房价预测
洛屿 · 2023-07-26 · via 洛屿的小站
#include "global_define.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M_PI 3.14159265358979323846

double normal_random() {
double u1 = rand() / (RAND_MAX + 1.0);
double u2 = rand() / (RAND_MAX + 1.0);
double z = sqrt(-2.0 * log(u1)) * sin(2.0 * M_PI * u2);
return z;
}
struct Pair {
double* first;
double second;
};

typedef struct Pair Pair;
const int iterations = 40000;
const int log_step = 50;
double learningrate = 0.00125;
double data[SIZE][LABELS];
double train_data[TRAIN_SIZE][LABELS];
double maximums[LABELS] = { 0.0 };
double minimums[LABELS] = { 0.0 };
double avgs[LABELS] = { 0.0 };
int init = 0;
double w[DATA_SIZE] = {
1.76405235,
0.40015721,
0.97873798,
2.2408932,
1.86755799,
-0.97727788,
0.95008842,
-0.15135721,
-0.10321885,
0.4105985,
0.14404357,
1.45427351,
0.76103773, };
double b = 0;
////////////////////////////
#include "array.h"
#include "dataprocess.h"
#include "Network.h"
#include "vectorcomputation.h"
////////////////////////////

int main() {
printhello(1);
load_data();
//数据集 TRAIN_SIZE * SIZE
double x[TRAIN_SIZE][DATA_SIZE];
//double** x = (double**)malloc(sizeof(double*) * TRAIN_SIZE);
//for (int i = 0; i < TRAIN_SIZE; i++) {
// x[i] = (double*)malloc(SIZE * sizeof(double));
//}
for (int i = 0; i < TRAIN_SIZE; i++) {
for (int j = 0; j < DATA_SIZE; j++) {
x[i][j] = train_data[i][j];
}
}

//标签集 TRAIN_SIZE * 1
double y[TRAIN_SIZE];
//double* y = (double*)malloc(sizeof(double) * TRAIN_SIZE);
for (int i = 0; i < TRAIN_SIZE; i++) {
y[i] = train_data[i][DATA_SIZE];
}
__init__();
printf("按下任意按键以开始训练...\n");
system("pause");

train(x, y);

return 0;
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
////////////////////////////////__ARRAY_H__//////////////////////////////////

double getsum(const double* arr, const int size) {
double ans = 0;
for (int i = 0; i < size; i++) {
ans += arr[i];
}
return ans;
}

double getavg(const double* arr, const int size) {
return getsum(arr, size) / (double)size;
}

double getmax_col(const double arr[TRAIN_SIZE][LABELS], const int col) {
double ans = -23333;
for (int i = 0; i < TRAIN_SIZE; i++) {
if (arr[i][col] > ans) {
ans = arr[i][col];
}
}

return ans;
}

double getmin_col(const double arr[TRAIN_SIZE][LABELS], const int col) {
double ans = 23333;

for (int i = 0; i < TRAIN_SIZE; i++) {
if (arr[i][col] < ans) {
ans = arr[i][col];
}
}

return ans;
}

double getsum_row(const double arr[TRAIN_SIZE][LABELS], const int col) {
double ans = 0;
for (int i = 0; i < TRAIN_SIZE; i++) {
ans += arr[i][col];
}
return ans;
}

double getavg_col(const double arr[TRAIN_SIZE][LABELS], const int col) {
return getsum_row(arr, col) / (double)TRAIN_SIZE;
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////__DATAPROCESS_H__///////////////////////////////
void load_data() {
printf("开始载入数据...\n");
const char* datafile = "train.data";
FILE* fdata = fopen(datafile, "r");
if (fdata == NULL) {
printf("文件%s打开失败,程序即将退出..", datafile);
exit(-11);
}
int ysize = 0;
while (!feof(fdata)) {
//按着每行14份数据为一组进行分割
for (int i = 0; i < LABELS; i++) {
fscanf(fdata, "%lf", &data[ysize][i]);
}
ysize++;
}

fclose(fdata);

// copy(data, data_slice, 0, 0, TRAIN_SIZE, LABELS);
for (int i = 0; i < TRAIN_SIZE; i++) {
for (int j = 0; j < LABELS; j++) {
train_data[i][j] = data[i][j];
}
}

//for (int i = 0; i < TRAIN_SIZE * LABELS; i++) {
// printf("%lf ", train_data[i / 14][i % 14]);
// if (i % 14 == 0)printf("\n");
//}

for (int i = 0; i < LABELS; i++) {
maximums[i] = getmax_col(train_data, i);
minimums[i] = getmin_col(train_data, i);
avgs[i] = getavg_col(train_data, i);
//printf("%lf %lf %lf\n", maximums[i], minimums[i], avgs[i]);
}

//归一化
for (int x = 0; x < TRAIN_SIZE; x++) {
for (int y = 0; y < DATA_SIZE; y++) {
if (maximums[y] - minimums[y] == 0)continue;
data[x][y] = (data[x][y] - minimums[y]) / (maximums[y] - minimums[y]);
}
}

/*for (int y = 0; y < TRAIN_SIZE; y++) {
printf("%.5lf ", data[y][0]);
}
printf("\n");*/

for (int i = 0; i < TRAIN_SIZE; i++) {
for (int j = 0; j < LABELS; j++) {
train_data[i][j] = data[i][j];
}
}
printf("数据载入完成\n");
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
///////////////////////////////__NETWORK_H__/////////////////////////////////
/// <summary>
/// 初始化
/// </summary>
void __init__() {
init = 1;
printf("***w***\n");
for (int i = 0; i < DATA_SIZE; i++) {
//w[i] = 1.0 * normal_random();
printf("%.2lf ", w[i]);
}
printf("\n");
b = 0.0;
printf("初始化完成\n");
}

/// <summary>
/// 前向计算
/// </summary>
/// <param name="x">数据集,大小为TRAIN_SIZE * DATA_SIZE</param>
/// <param name="z">用于接受返回值的数组,其值为基于当前w b计算得来的预测值</param>
void forward(const double x[TRAIN_SIZE][DATA_SIZE], double z[TRAIN_SIZE]) {
if (!init) {
printf("网络未进行初始化!--forward 错误代码:-1");
exit(-1);
}

for (int i = 0; i < TRAIN_SIZE; i++) {
z[i] = vectordot(x[i], w) + b;
//printf("%lf\n",z[i]);
}
}

/// <summary>
/// 计算损失
/// </summary>
/// <param name="z">当前w b下的预测值[将用于与标签值比较],大小为TRAIN_SIZE</param>
/// <param name="y">标签值,大小为TRAIN_SIZE</param>
/// <returns>一个double,代表预测值与实际值的误差,误差越小,返回值越小</returns>
double loss(double z[TRAIN_SIZE],const double y[TRAIN_SIZE]) {
if (!init) {
printf("网络未进行初始化!--loss 错误代码:-2");
exit(-2);
}
//printf("::vectorsub ");
double error[TRAIN_SIZE];
vectorsub(z, y, error);
/*for (int i = 0; i < TRAIN_SIZE; i++) {
printf("%lf ", z[i]);
}
printf("\n");*/

//printf("::vectormultiply ");
double cost[TRAIN_SIZE];
vectormultiply(error, error, cost);

/*for (int i = 0; i < TRAIN_SIZE; i++) {
printf("%.3lf ", cost[i]);
}
printf("\n***********************************\n");*/

double dcost = getavg(cost, TRAIN_SIZE);

return dcost;
}

/// <summary>
/// 梯度计算
/// </summary>
/// <param name="x">数据集,大小为TRAIN_SIZE * DATA_SIZE</param>
/// <param name="y">标签集,大小为TRAIN_SIZE</param>
/// <returns>返回Pair 第一项为梯度w 第二项为梯度b</returns>
Pair gradient(const double x[TRAIN_SIZE][DATA_SIZE], const double y[TRAIN_SIZE]) {
if (!init) {
printf("网络未进行初始化!--gradient 错误代码:-3");
exit(-3);
}
//printf("gradient::forward\n");
//z : 404 * 1
//y : 404 * 1
//x : 404 * 13
double z[TRAIN_SIZE];
forward(x, z);
/*for (int i = 0; i < TRAIN_SIZE; i++) {
printf("%.3lf ", z[i]);
}
printf("\n");*/

//printf("gradient::sub\n");
double tgradient_b[TRAIN_SIZE];

vectorsub(z, y, tgradient_b);

/*for (int i = 0; i < TRAIN_SIZE; i++) {
printf("%lf %d\n", tgradient_b[i], i);
}*/

//printf("gradient::multiply2\n");

double tgradient_w[TRAIN_SIZE][DATA_SIZE];
for (int i = 0; i < TRAIN_SIZE; i++) {
for (int j = 0; j < DATA_SIZE; j++) {
tgradient_w[i][j] = tgradient_b[i] * x[i][j];
//printf("%.2lf ", tgradient_w[i][j]);
}
//printf("\n");
}

//for (int i = 0; i < TRAIN_SIZE; i++) {
// vectormultiply(tgradient_b, x[i], tgradient_w[i]);
//}

//printf("end multiply\n");

double gradient_w[DATA_SIZE];
//列均值
for (int i = 0; i < DATA_SIZE; i++) {
double sum = 0.0;
for (int x = 0; x < TRAIN_SIZE; x++) {
sum += tgradient_w[x][i];
//printf("::gra%lf %d\n", tgradient_w[x][i], i);
}
gradient_w[i] = sum / (double)TRAIN_SIZE;
}
//printf("end avg\n");

double gradient_b = getavg(tgradient_b, TRAIN_SIZE);
/*for (int i = 0; i < TRAIN_SIZE; i++) {
free(tgradient_w[i]);
}
free(tgradient_w);
free(tgradient_b);
free(z);*/
//printf("%lf\n", gradient_b);
return (Pair) { gradient_w, gradient_b };
}

/// <summary>
/// 更新权重w, b
/// </summary>
/// <param name="gradient_w">线性的回归的斜率</param>
/// <param name="gradient_b">线性回归的坐标轴位移</param>
void update(const double gradient_w[DATA_SIZE], const double gradient_b) {
if (!init) {
printf("网络未进行初始化!--update 错误代码:-4");
exit(-4);
}
for (int i = 0; i < DATA_SIZE; i++) {
w[i] -= learningrate * gradient_w[i];
}
b -= learningrate * gradient_b;
}

/// <summary>
/// 训练主体
/// </summary>
/// <param name="x">数据集,大小为TRAIN_SIZE * DATA_SIZE</param>
/// <param name="y">标签集,大小为TRAIN_SIZE</param>
void train(const double x[TRAIN_SIZE][DATA_SIZE], const double y[TRAIN_SIZE]) {
if (!init) {
printf("网络未进行初始化!--train 错误代码:-5");
exit(-5);
}

printf("开始训练\n");
double L = -1;
for (int i = 0; i < iterations; i++) {
if (i == iterations * 0.3) {
learningrate /= 2;
}
if (i == iterations * 0.5) {
learningrate /= 2;
}
if (i == iterations * 0.8) {
learningrate /= 2;
}
//printf("进行forward \n");
double z[TRAIN_SIZE];
forward(x, z);
//printf("计算loss \n");
L = loss(z, y)/100;
/*for (int i = 0; i < TRAIN_SIZE; i++) {
printf("%lf %lf\n", z[i], y[i]);
}*/

//printf("开始gradient \n");
Pair pair = gradient(x, y);
double* gradient_w = pair.first;
double gradient_b = pair.second;
//printf("进行更新\n");
update(gradient_w, gradient_b);
if ((i + 1) % log_step == 0) {
printf("> iter %d, loss %.10lf lr %lf\n", i, L, learningrate);
}
}
printf("训练完成,共训练轮次:%d轮 最终得到的参数为:\n", iterations);
//printf("************gradient_w************\n");
printgradientw();
for (int i = 0; i < DATA_SIZE; i++) {
printf("\033[36mw[%2d] = %64.60lf\033[m\n", i, w[i]);
}
//printf("\n************gradient_b************:\n");
printgradientb();
printf("\033[36m b = %64.60lf\033[m\n\n", b);
printf("基于该参数的模型预测损失为:%lf\n", L);

printf("正在导出模型...\n");
FILE* fout = fopen("train_finish.luoy", "w");
if (fout == NULL) {
printf("模型导出错误,程序即将退出");
system("pause");
exit(-12);
}
for (int i = 0; i < DATA_SIZE; i++) {
fprintf(fout, "%.60lf ", w[i]);
}
fprintf(fout, "\n");
fprintf(fout, "%.60lf", b);
for (int i = 0; i < LABELS; i++) {
fprintf(fout,"\n%lf %lf %lf", maximums[i], minimums[i], avgs[i]);
}
fclose(fout);
printf("模型导出完成!\n");

printbye(1);
printhello(1);
printf("按任意键退出...\n");
system("pause");
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
///////////////////////////__VECTORCOMPUTATION_H__///////////////////////////
//add, subtract, multiply and divide
/// <summary>
/// 两个DATA_SIZE大小的一纬向量相乘,返回一个两个向量每项乘积之和
/// </summary>
/// <param name="x">向量1</param>
/// <param name="arr">向量2</param>
/// <returns></returns>
double vectordot(const double x[DATA_SIZE], const double arr[DATA_SIZE]) {
double ans = 0;

for (int i = 0; i < DATA_SIZE; i++) {
ans += x[i] * arr[i];
}
return ans;
}

/// <summary>
/// 两个一维向量相减,返回一维向量
/// </summary>
/// <param name="x">减数</param>
/// <param name="y">被减数</param>
/// <param name="ans">用于接收返回值的数组</param>
/// <returns></returns>
void vectorsub(const double x[TRAIN_SIZE], const double y[TRAIN_SIZE], double ans[TRAIN_SIZE]) {
for (int i = 0; i < TRAIN_SIZE; i++) {
ans[i] = x[i] - y[i];
}
}

/// <summary>
/// 两个一维向量相乘
/// </summary>
/// <param name="x">向量1</param>
/// <param name="y">向量2</param>
/// <param name="ans">用于接收返回值的数组</param>
void vectormultiply(const double x[TRAIN_SIZE], const double y[TRAIN_SIZE], double ans[TRAIN_SIZE]) {
for (int i = 0; i < TRAIN_SIZE; i++) {
ans[i] = x[i] * y[i];
}
}