zoukankan      html  css  js  c++  java
  • C# + Matlab 实现计件工时基于三层BP神经网络的拟合--真实项目

    工序工时由该工序的工艺参数决定,有了工时后乘以固定因子就是计件工资。一般参考本地小时工资以及同类小时工资并考虑作业的风险等因素给出固定因子

    采用的VS2010 , Matlab2015a 64,  开发端是win7 64 , 部署端是win2012 R2 Datacenter 64

    Matlab部分

    下面是样本数据:

    注意样本数据要尽可能全面,比方这里会交换L与R后做为另一组样本数据一起交给系统训练

    打钩的数据会抽取来训练,WTime是目标,所以5个输入1个输出。

    训练代码

    clc
    clear
    excel=xlsread('frmZJ_KB_SalaryParamAdmin2011140841.xls');
    % 训练集——个样本
    P_Train=excel(:,[4 5 11 7 8])';  %注意运算时需要转置矩阵
    T_Train=excel(:,9)';
    % 测试集——个样本
    rndSample=randperm(size(excel,1),500); %随机选择100个作为样本
    P_Test=P_Train(:,rndSample);
    T_Test=T_Train(:,rndSample);
    %% III. 数据归一化
    [p_train, ps_input] = mapminmax(P_Train,0,1);
    p_test = mapminmax('apply',P_Test,ps_input);
    save('ps_input.mat','ps_input');
    [t_train, ps_output] = mapminmax(T_Train,0,1);
    save('ps_output.mat','ps_output')
    N = size(P_Test,2);
    %% IV. BP神经网络创建、训练及仿真测试
    %%
    % 1. 创建网络
    net = newff(p_train,t_train,60);
    
    %%
    % 2. 设置训练参数
    net.trainParam.epochs = 10000;
    net.trainParam.goal = 1e-5;
    net.trainParam.lr = 0.01;
    
    %%
    % 3. 训练网络
    net = train(net,p_train,t_train);
    save('ZJPrediction.mat','net');
    %%
    % 4. 仿真测试
    t_sim = sim(net,p_test);
    
    %%
    % 5. 数据反归一化
    T_sim = mapminmax('reverse',t_sim,ps_output);
    
    
    %% V. 性能评价
    %%
    % 1. 相对误差error
    error = abs(T_sim - T_Test)./T_Test;
    
    %%
    % 2. 决定系数R^2
    R2 = (N * sum(T_sim .* T_Test) - sum(T_sim) * sum(T_Test))^2 / ((N * sum((T_sim).^2) - (sum(T_sim))^2) * (N * sum((T_Test).^2) - (sum(T_Test))^2)); 
    
    %%
    % 3. 结果对比
    result = [T_Test' T_sim' error']
    
    %% VI. 绘图
    figure
    plot(1:N,T_Test,'b:*',1:N,T_sim,'r-o')
    legend('真实值','预测值')
    xlabel('预测样本')
    ylabel('输出值')
    string = {'测试集预测结果对比';['R^2=' num2str(R2)]};
    title(string)
    View Code

    训练好的模型要保存起来,还有归一化参数,下面3个打钩的文件要发布到生产环境中

    下面是需要封成dll的函数,里面采用了绝对路径,因为封装成Windows Service后matlab的工作目录会在C盘下的临时目录

    function r=PredictionZJWTime(d)
    load('D:MatlabServerps_input.mat','ps_input');
    load('D:MatlabServerps_output.mat','ps_output');
    load('D:MatlabServerJPrediction.mat','net');
    P_Test=d';
    p_test = mapminmax('apply',P_Test,ps_input);
    %%
    % 4. 仿真测试
    t_sim = sim(net,p_test);
    
    %%
    % 5. 数据反归一化
    T_sim = mapminmax('reverse',t_sim,ps_output);
    r=[d T_sim' T_sim'*0.0062];
    end
    View Code

    下面在matlab环境下测试所封装的函数

    clc
    clear
    excel=xlsread('frmZJ_KB_SalaryParamAdmin2011120839.xls');
    % 训练集——个样本
    P_Train=excel(:,[4 5 11 7 8])';  %注意运算时需要转置矩阵
    T_Train=excel(:,9)';
    % 测试集——个样本
    rndSample=randperm(size(excel,1),100); %随机选择100个作为样本
    P_Test=P_Train(:,rndSample);
    T_Test=T_Train(:,rndSample);
    
    T_Sim=PredictionZJWTime(P_Test');
    T_Sim(:,6) - T_Test'
    View Code

    生成dll库文件

     

    生成的dll文件一般有2个文件。ZJSim与ZJSimNative,后面带Native是本地类库,调用参数有点区别--Class Name可自己修改

    另外还要copy  MWArry.dll文件 一般安装在 C:Program FilesMATLABMATLAB Production ServerR2015a oolboxdotnetbuilderinwin64v2.0MWArray.dll

    C#部分

    分装成windows服务,并对外以WCF HttpBinding的方式发布, 本来想直接挂在IIS下,但是一直没调试成功

    服务类

        [ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, MaxItemsInObjectGraph = 2147483647, IgnoreExtensionDataObject = true, UseSynchronizationContext = false)]
        public class HDMatlabServiceImp : IHDMatlabService
        {
            
            public List<ZJPredictionInfo> PredictionForZJ(List<ZJPredictionInfo> inData)
            {
                var inMatrix=new double[inData.Count,5];
                for (int row=0;row<inData.Count;row++)
                {
                    var it=inData[row];
                    inMatrix[row, 0] = it.L;
                    inMatrix[row, 1] = it.R;
                    inMatrix[row, 2] = it.D;
                    inMatrix[row, 3] = it.I;
                    inMatrix[row, 4] = it.S;
                    //inMatrix[row, 5] = it.WTime;
                    //inMatrix[row, 6] = it.SalaryPerUnit;
                }
    
                var srv = new ZJWTimeSimulater();
    
    
                var outMatrix = (double[,])srv.PredictionZJWTime(inMatrix);
                for (int i = 0; i < inData.Count; i++)
                {
                    inData[i].SimWTime = outMatrix[i, 5];
                    inData[i].SimSalaryPerUnit = outMatrix[i, 6];
                }
                return inData;
            }
        }
    }
    View Code

    托管类,对应binging的配置方在app.config中貌似没反映,所以就整到代码里,

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.Configuration;
    using HD.Matlab.IService;
    
    namespace HD.Matlab.Service
    {
        public class HDMatlabServiceHost
        {
            public static readonly HDMatlabServiceHost Instance = new HDMatlabServiceHost();
            private HDMatlabServiceHost() { }
    
            private ServiceHost _Host;
    
            public void Start(params string[] args)
            {
                if (_Host == null || _Host.State == CommunicationState.Faulted || _Host.State == CommunicationState.Closed)
                {
                    _Host = new ServiceHost(typeof(HDMatlabServiceImp));
                    //_Host.AddServiceEndpoint(typeof(IHDMatlabService), new NetTcpBinding(SecurityMode.None),
                    //                        ConfigurationManager.AppSettings["HDMatlabServiceURL"]
                    //                         );
                    var httpBing = new BasicHttpBinding(BasicHttpSecurityMode.None);
                    httpBing.CloseTimeout = new TimeSpan(10, 10, 10);
                    httpBing.MaxReceivedMessageSize = 2147483647;
                    httpBing.MaxBufferSize = 2147483647;
                    httpBing.MaxBufferPoolSize = 99999999;
                    httpBing.ReaderQuotas.MaxArrayLength = 99999999;
                    httpBing.OpenTimeout = new TimeSpan(10, 10, 10);
                    httpBing.SendTimeout = new TimeSpan(10, 10, 10);
                    httpBing.ReceiveTimeout = new TimeSpan(10, 10, 10);
                    httpBing.AllowCookies = true;
          
                    _Host.AddServiceEndpoint(typeof(IHDMatlabService), httpBing,
                            ConfigurationManager.AppSettings["HDMatlabServiceURL_Http"]
                                );
    
    
    
                }
    
                _Host.Open();
                Console.WriteLine("设备控制服务启动成功");
            }
    
            public void Stop()
            {
                if (_Host != null) _Host.Close();
                Console.WriteLine("设备控制服务关闭");
            }
        }
    }
    View Code

    Windows服务

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using HD.Matlab.Service;
    
    namespace HD.Matlab.WinSrv
    {
        public partial class MatlabService : ServiceBase
        {
            public MatlabService()
            {
                InitializeComponent();
            }
    
            protected override void OnStart(string[] args)
            {
                HDMatlabServiceHost.Instance.Start();
            }
    
            protected override void OnStop()
            {
                HDMatlabServiceHost.Instance.Stop();
            }
        }
    }
    View Code

    另外需要注意的是Win服务编译时需要选择AnyCpu ,使用x86时发现报错

    最后对一部数据进行测试发现拟合效果还可以,多数差异在1%以内

    上面代码基本就是全部了,需要完整项目留邮箱

  • 相关阅读:
    rhel 6.4 + udev+ 11.2.0.3 + gi + asm+ rac 双节点安装
    rhel 6.4 + udev + 11.2.0.3 + asm 单点安装
    vmware 中linux虚拟机动态添加硬盘
    flashback drop
    flashback query
    11g crsctl start/stop crs 和 crsctl start/stop cluster 的关系
    10g crs 启动报错的记录
    检测数据库日志的切换频率及归档文件大小的sql
    用widthStep的方法来增加某范围的像素----与imageROI对比
    用imageROI来增加某范围的像素
  • 原文地址:https://www.cnblogs.com/wdfrog/p/13983698.html
Copyright © 2011-2022 走看看