会员运营方案纲要和培训

一、会员运营目标:

1.提高会员量以及会员活跃度。
2.将会员更好的分级分类。
3.针对不同类型的会员做精准营销

二、目标关键字定义

1.会员量
提高会员量包括提高/降低以下指标:

  • i. 会员增长/会员增长速度
  • ii. 有效会员量/有效会员增量
  • iii. 会员留存率/流失率
  • iv. 核心用户(更多的订单和交易额)/一般会员
    RFM模型
    以月为计算周期,每月下单会员为对象,根据会员最近一次消费(Recency)、消费频率(Frequency)、消费金额(Monetary)三个维度进行细分会员群体。

    将其中几类会员整合后最终将会员划分为四类:最好会员(最近消费的时间短,经常购买且购买金额大的会员)、重点突破会员(不经常购买但购买金额大的会员)、重点维护会员(经常购买但购买金额小的会员)、一般会员(最近消费时间长,不经常购买且购买金额小的会员)

    划分标准:
    1)R小于等于15天,F大于等于8次,M大于等于平均客单价为最好会员
    2)F小于8次,M大于等于平均客单价为重点突破会员
    3)F大于等于8次,M小于平均客单价为重点维护会员
    4)R大于15天,F小于8次,M小于于平均客单价为一般会员

  • v. 种子用户(更多的分享和推荐)
    • 关于商品的图文消息、测试消息等的转发数。(有一定误差)
    • 要求技术对登陆用户的分享次数做出统计,以便筛选出乐于分享的用户,给予特惠、引导分享,并将其转化为核心用户,如奖章。

2.会员活跃度

  • i. 轻度活跃行为(根据轻-重排列):
    • a) 阅读资讯(微信、海报、传单) 统计方法:
    • b) 登陆网站(或通过链接、二维码直接进入官网某页)
      统计方法:取cnzz的数据,PV 和平均访问深度,作为登陆网站的轻度活跃
  • ii. 中度活跃行为(根据轻-重排列):
    • a) 在网站使用“搜索”等功能 统计方法:
      • 1.在cnzz查看【XX 】(手机版)页面的访问次数。(有一定误差)
    • b) 将商品添加进“购物车” 统计方法:
      • 1.在cnzz查看【XX】(手机版)页面的访问次数。(有一定误差)
      • 2.要求技术对重要的按钮增加统计次数,“搜索”和“购物车”按钮分别被点击了多少次。
    • c) 分享/推荐商品、页面、活动等给好友 统计方法:
      1.暂不能统计,要求技术加入多个可以“分享”或“推荐”的按钮,并可以统计其次数频率。
  • iii. 核心活跃行为(主要为两类,【互动】和【订单】,目前能统计到大部分为核心订单活跃):
    • 通过微信群、公众号、客服电话等主动参与活动,或主动反馈的建议。 统计方法:由于此类用户较少,采取手动统计。统计在《互动用户统计表》内
    • 完成购物流程。 统计方法:通过后台订单即可统计 注:
      • 1.一个活跃会员有多种表现形式。(包括以上情形,但不限于)
      • 2.以上指标的单位有 次数(登陆、下单、分享、参与活动等)和 时常 (登陆、停留页面等)
      • 3.会员的活跃度是一个较长期的表现,理想状况下,一个会员的活跃度,应该是以“一定时间内,以上不同事件的触发总数/时长,再根据加权平均后取得”

3.分级分类方式

  • i. 分类方式:
    • a) 基本会员属性(以基本-高级排列):年龄、性别、职业、小区(企业)、收入、兴趣爱好
    • b) 会员活跃属性:
      • i. 活跃渠道:
        1. 【媒体】查看资讯、活动(目前仅有微信公众号)-
        2. 【官网】登陆官网 – 查看商品或者促销页
        3. 【线下】逛门店、与店员聊天
      • ii. 活跃方式:
        1. 被动浏览(如基本只看一下公众号推送的咨询、商品、专区)
        2. 主动查阅(如查看页面较多但停留较短,喜欢逛、了解等)
        3. 目的性明确(如频繁利用“搜索栏”,或主动问询是否有XX商品等)
        4. 习惯性下单(可能是经常购买食材类做饭的用户)
        5. 赠品型下单(如多次订单,每次订单金额都较大等)
      • iii. 活跃程度:根据【会员活跃度指标】的时常、次数等综合判断分级,大约分为4级:
        1. 一次性会员(不登陆、不互动,可能仅仅是在推广活动中,为了获取小礼品而注册的)
        2. 沉默会员(偶尔查看资讯,偶尔浏览商品和活动,不互动,不下单)
        3. 一般会员(有时查看资讯和活动,偶尔下单)
        4. 忠诚会员/潜力忠诚会员(经常查看资讯、活动,有下单的习惯/多次参与活动等)
  • ii. 分级方式:
    • a) 会员的消费
    • b) 会员的活跃度
    • c) 会员的传播性应根据以上3个层次来综合分级。
  • iii. 分类模板:
    以活跃度为核心进行分级.

4.精准营销:

三、会员运营步骤:

漏斗模型
将目标拆分并概括为修改后的“AARRR”转化漏斗模型,被导入的一部分用户会在某个环节流失,而剩下的用户则继续下去,直到实现最终的转化和价值。(暂只考虑前4步)。

  • A. 获取用户
    吸引流量/用户量增长 【线上】 /让潜在客户首次注册(线下)
  • B. 激发活跃
    引导用户完成某些“指定动作”,如注册(线下推广用户)。其他制定动作待定
  • C. 提高留存
    留住一个老用户的成本要低于获取新用户的成本。降低流失,让老用户(完成一次活跃激发的用户更好的留下来,再次完成“指定动作”,如登陆、浏览、下单)
  • D. 传播推荐
    人们更容易相信来自亲朋、有影响力的人士(如知名人士、公司领导等)的推荐。
  • E. 增加收入

四、具体方法概述

  • A. 获取用户方法
    • i. 自然增长(在内容中添加更多的可供传播的内容,如引导分享等)
    • ii. 线上活动增长
    • iii. 线下推广增长
  • B. 激发活跃方法
    • i. 用户补贴
    • ii. 游戏化
    • iii. 诱饵效应
    • iv. 降低活跃门槛(优化流程和性能)
    • v. 脚本化自动运营(托)
  • C. 提高留存方法
    • i. 唤醒机制
      • a) 告知进展
      • b) 提供奖励
      • c) 个性化推荐
    • ii. 有损服务
    • iii. 社交维系
  • D. 传播推荐方法
    • i.活动传播(使用优惠、赠品等方式推广)
    • ii. 病毒营销(K因子、循环周期)

实现方法概括:

  • 内容运营:
    内容运营为传播、转化的核心。内容运营一般异步的,往往是先发布内容,用户后阅读、进行行为。

    • 1.官网商品页、活动页、着陆页(如扫二维码、点击群内链接,直接进入某专题页
    • 2.微信服务号、
    • 3.订阅号的图文消息、商品消息。
  • 渠道运营:
    渠道运营这里指的是可以直接联系到用户的方法。可以用于较为重要的消息通知,如邀请老用户参与互动、回馈核心用户、调查某非常需要的数据等。

    • 1.客服电话回访
    • 2.群短信通知
  • 社群运营
    社群运营同步性较好、及时性较强,一般能更快的获得用户的回馈,可以有效地提高某阶段的转化率。缺陷是如果有投诉,在社群内容易引起波动,使观望用户退却。

    • 1.微信
    • 2.QQ群
  • 活动运营
    通过各种优惠活动,能够促进各个环节的用户积极性,用户回馈明确。尤其在于新用户增长方面

    • 1.线上活动(官网、公众号、朋友圈转发等)
    • 2.线下活动(联合门店、市场)

TensorFlow 深度学习笔记 卷积神经网络

Convolutional Networks

deep dive into images and convolutional models

Convnet

BackGround

  • 人眼在识别图像时,往往从局部到全局
  • 局部与局部之间联系往往不太紧密
  • 我们不需要神经网络中的每个结点都掌握全局的知识,因此可以从这里减少需要学习的参数数量

Weight share

  • 但这样参数其实还是挺多的,所以有了另一种方法:权值共享

Share Parameters across space

  • 取图片的一小块,在上面做神经网络分析,会得到一些预测
  • 将切片做好的神经网络作用于图片的每个区域,得到一系列输出
  • 可以增加切片个数提取更多特征
  • 在这个过程中,梯度的计算跟之前是一样的

Concept

  • Patch/Kernel:一个局部切片
  • Depth: 数据的深度,图像数据是三维的,长宽和RGB,神经网络的预测输出也属于一维
  • Feature Map:每层Conv网络,因为它们将前一层的feature映射到后一层(Output map)

  • Stride: 移动切片的步长,影响取样的数量
  • 在边缘上的取样影响Conv层的面积,由于移动步长不一定能整除整张图的像素宽度,不越过边缘取样会得到Valid Padding, 越过边缘取样会得到Same Padding
  • Example

  • 用一个3×3的网格在一个28×28的图像上做切片并移动
  • 移动到边缘上的时候,如果不超出边缘,3×3的中心就到不了边界
  • 因此得到的内容就会缺乏边界的一圈像素点,只能得到26×26的结果
  • 而可以越过边界的情况下,就可以让3×3的中心到达边界的像素点
  • 超出部分的矩阵补零就行

Deep Convnet

在Convnet上套Convnet,就可以一层一层综合局部得到的信息

OutPut

将一个deep and narrow的feature层作为输入,传给一个Regular神经网络

Optimization

Pooling

将不同Stride的卷积用某种方式合并起来,节省卷积层的空间复杂度。

  • Max Pooling
    在一个卷积层的输出层上取一个切片,取其中最大值代表这个切片
  • 优点
  • 不增加需要调整的参数
  • 通常比其他方法准确
  • 缺点:更多Hyper Parameter,包括要取最值的切片大小,以及去切片的步长

LENET-5, ALEXNET

  • Average Pooling
    在卷积层输出中,取切片,取平均值代表这个切片

1×1 Convolutions

在一个卷积层的输出层上,加一个1×1的卷积层,这样就形成了一个小型的神经网络。

  • cheap for deeper model
  • 结合Average Pooling食用效果更加

    Inception

    对同一个卷积层输出,执行各种二次计算,将各种结果堆叠到新输出的depth方向上

TensorFlow卷积神经网络实践

数据处理

  • dataset处理成四维的,label仍然作为one-hot encoding
    def reformat(dataset, labels, image_size, num_labels, num_channels):
    dataset = dataset.reshape(
        (-1, image_size, image_size, num_channels)).astype(np.float32)
    labels = (np.arange(num_labels) == labels[:, None]).astype(np.float32)
    return dataset, labels
  • 将lesson2的dnn转为cnn很简单,只要把WX+b改为conv2d(X)+b即可
  • 关键在于conv2d

`conv2d

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

给定四维的inputfilter tensor,计算一个二维卷积

Args:
  • input: A Tensor. type必须是以下几种类型之一: halffloat32float64.
  • filter: A Tensor. type和input必须相同
  • strides: A list of ints.一维,长度4, 在input上切片采样时,每个方向上的滑窗步长,必须和format指定的维度同阶
  • padding: A string from: "SAME", "VALID". padding 算法的类型
  • use_cudnn_on_gpu: An optional bool. Defaults to True.
  • data_format: An optional string from: "NHWC", "NCHW", 默认为"NHWC"
    指定输入输出数据格式,默认格式为”NHWC”, 数据按这样的顺序存储:
    [batch, in_height, in_width, in_channels]
    也可以用这种方式:”NCHW”, 数据按这样的顺序存储:
    [batch, in_channels, in_height, in_width]
  • name: 操作名,可选.
Returns:

Tensor. type与input相同

Given an input tensor of shape [batch, in_height, in_width, in_channels]
and a filter / kernel tensor of shape
[filter_height, filter_width, in_channels, out_channels]

conv2d实际上执行了以下操作:

  1. 将filter转为二维矩阵,shape为
    [filter_height * filter_width * in_channels, output_channels].
  2. 从input tensor中提取image patches,每个patch是一个virtual tensor,shape[batch, out_height, out_width, filter_height * filter_width * in_channels].
  3. 将每个filter矩阵和image patch向量相乘

具体来讲,当data_format为NHWC时:

output[b, i, j, k] =
    sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
                    filter[di, dj, q, k]

input 中的每个patch都作用于filter,每个patch都能获得其他patch对filter的训练
需要满足strides[0] = strides[3] = 1. 大多数水平步长和垂直步长相同的情况下:strides = [1, stride, stride, 1].
– – –

  • 然后再接一个WX+b连Relu连WX+b的全连接神经网络即可

Max Pooling

在tf.nn.conv2d后面接tf.nn.max_pool,将卷积层输出减小,从而减少要调整的参数

max_pool

tf.nn.max_pool(value, ksize, strides, padding, data_format='NHWC', name=None)

Performs the max pooling on the input.

Args:
  • value: A 4-D Tensor with shape [batch, height, width, channels] and
    type tf.float32.
  • ksize: A list of ints that has length >= 4. 要执行取最值的切片在各个维度上的尺寸
  • strides: A list of ints that has length >= 4. 取切片的步长
  • padding: A string, either 'VALID' or 'SAME'. padding算法
  • data_format: A string. ‘NHWC’ and ‘NCHW’ are supported.
  • name: 操作名,可选
Returns:

Tensor with type tf.float32. The max pooled output tensor.

十大最热门人工智能技术

人工智能(AI)技术市场正在蓬勃发展。除了大肆炒作和媒体的日益关注外,众多初创公司和互联网巨头都在竞相加入进来,企业的投资力度和采用程度随之大幅提升。Narrative Science公司在去年的一项调查发现,38%的企业已经在使用人工智能技术,到2018年这个比例有望增长到62%。弗雷斯特研究公司预测,2017年人工智能领域的投入将比2016年猛增300%。IDC公司估计,人工智能市场将从2016年的80亿美元,增加到2020年的470亿美元。

“人工智能”是1955年杜撰的一个术语,用来描述计算机科学领域的一个新兴分支学科。如今,人工智能包括一系列广泛的技术和工具,有些久经时间的考验,而另一些还比较新颖。为了帮助了解什么是热门技术、什么不是热门技术,弗雷斯特研究公司刚刚发布了关于人工智能的TechRadar报告(面向应用软件开发专业人员),该报告详细深入地分析了企业应该考虑采用、以支持人类决策的13种技术。

基于弗雷斯特研究公司的分析结果,本人在下面列出了10种最热门的人工智能技术:

  1. 自然语言生成:利用计算机数据生成文本。目前应用于客户服务、报告生成以及总结商业智能洞察力。代表性厂商包括:Attivio、Cambridge Semantics、Digital Reason、Lucidworks、Narrative Science和SAS。
  2. 语音识别:将人类语音转录和转换成对计算机应用软件来说有用的格式。目前应用于交互式语音应答系统和移动应用领域。代表性厂商包括:NICE、Nuance Communications、OpenText和Verint Systems。
  3. 虚拟代理:弗雷斯特公司声称,“虚拟代理可谓是媒体界目前竞相报道的对象。”从简单的聊天机器人,到可以与人类进行交际的高级系统,不一而足。目前应用于客户服务和支持以及充当智能家居管理器。代表性厂商包括:亚马逊、苹果、Artificial Solutions、 Assist AI、Creative Virtual、谷歌、IBM、IPsoft、微软和Satisfi。
  4. 机器学习平台:不仅提供了设计和训练模型,并将模型部署到应用软件、流程及其他机器的计算能力,还提供了算法、应用编程接口(API)、开发工具包和训练工具包。目前应用于一系列广泛的企业应用领域,主要涉及预测或分类。代表性厂商包括:亚马逊、Fractal Analytics、谷歌、H2O.ai、微软、SAS和Skytree。
  5. 针对人工智能优化的硬件:这是专门设计的图形处理单元(GPU)和设备,其架构旨在高效地运行面向人工智能的计算任务。目前主要在深度学习应用领域发挥作用。代表性厂商包括:Alluviate、克雷、谷歌、IBM、英特尔和英伟达。
  6. 决策管理:引擎将规则和逻辑嵌入到人工智能系统,并用于初始的设置/训练和日常的维护和调优。这是一项成熟的技术,应用于一系列广泛的企业应用领域,协助或执行自动决策。代表性厂商包括:Advanced Systems Concepts、Informatica、Maana、Pegasystems和UiPat。
  7. 深度学习平台:一种特殊类型的机器学习,包括拥有多个抽象层的人工神经网络。目前主要应用于由很庞大的数据集支持的模式识别和分类应用领域。代表性厂商包括:Deep Instinct、Ersatz Labs、Fluid AI、MathWorks、Peltarion、 Saffron Technology和Sentient Technologies。
  8. 生物特征识别技术:能够支持人类与机器之间更自然的交互,包括但不限于图像和触摸识别、语音和身体语言。目前主要应用于市场研究。代表性厂商包括:3VR、Affectiva、Agnitio、FaceFirst、Sensory、Synqera和Tahzoo。
  9. 机器人流程自动化:使用脚本及其他方法,实现人类操作自动化,从而支持高效的业务流程。目前应用于人类执行任务或流程成本太高或效率太低的地方。代表性厂商包括:Advanced Systems Concepts、Automation Anywhere、Blue Prism、UiPath和WorkFusion。
  10. 文本分析和NLP:自然语言处理(NLP)使用和支持文本分析,为此它借助统计方法和机器学习方法,为理解句子结构及意义、情感和意图提供方便。目前应用于欺诈检测和安全、一系列广泛的自动化助理以及挖掘非结构化数据等领域。代表性厂商包括:Basis Technology、Coveo、Expert System、Indico、Knime、Lexalytics、Linguamatics、Mindbreeze、Sinequa、Stratifyd和Synapsify。

当然,如今公司企业可以从人工智能技术获得诸多好处,不过据弗雷斯特研究公司在去年进行的一项调查显示,采用人工智能方面也面临一些障碍,未打算投入于人工智能的公司表达了这些顾虑:

没有明确的商业理由 42%
不清楚人工智能可以用在什么地方 39%
缺乏所需的技能 33%
首先需要投入资金,以更新改造数据管理平台 29%
没有相应预算 23%
对于实施人工智能系统需要什么心里没底 19%
人工智能系统并没有得到验证 14%
没有合适的流程或治理 13%
人工智能尽是炒作,还没有落地 11%
自己没有所需的数据,或无法访问所需的数据 8%
不清楚人工智能是什么意思 3%

弗雷斯特研究公司得出结论,一旦企业克服了上述障碍,它们势必会得益于人工智能在面向客户的应用环境下加快转型,并编织成一个高度互联的企业信息网络。

免责申明:本站所有内容均来自网络,我们对文中观点保持中立,对所包含内容的准确性,可靠性或者完整性不提供任何明示或暗示的保证,请仅作参考。若有侵权,请联系删除。

BP神经网络

神经网络的计算过程

神经网络结构如下图所示,最左边的是输入层,最右边的是输出层,中间是多个隐含层,隐含层和输出层的每个神经节点,都是由上一层节点乘以其权重累加得到,标上“+1”的圆圈为截距项b,对输入层外每个节点:Y=w0*x0+w1*x1+…+wn*xn+b,由此我们可以知道神经网络相当于一个多层逻辑回归的结构。

图片描述

(图片来自UFLDL Tutorial
算法计算过程:输入层开始,从左往右计算,逐层往前直到输出层产生结果。如果结果值和目标值有差距,再从右往左算,逐层向后计算每个节点的误差,并且调整每个节点的所有权重,反向到达输入层后,又重新向前计算,重复迭代以上步骤,直到所有权重参数收敛到一个合理值。由于计算机程序求解方程参数和数学求法不一样,一般是先随机选取参数,然后不断调整参数减少误差直到逼近正确值,所以大部分的机器学习都是在不断迭代训练,下面我们从程序上详细看看该过程实现就清楚了。

神经网络的算法程序实现

神经网络的算法程序实现分为初始化、向前计算结果,反向修改权重三个过程。

1. 初始化过程

由于是n层神经网络,我们用二维数组layer记录节点值,第一维为层数,第二维为该层节点位置,数组的值为节点值;同样,节点误差值layerErr也是相似方式记录。用三维数组layer_weight记录各节点权重,第一维为层数,第二维为该层节点位置,第三维为下层节点位置,数组的值为某节点到达下层某节点的权重值,初始值为0-1之间的随机数。为了优化收敛速度,这里采用动量法权值调整,需要记录上一次权值调整量,用三维数组layer_weight_delta来记录,截距项处理:程序里将截距的值设置为1,这样只需要计算它的权重就可以了,

2. 向前计算结果

采用S函数1/(1+Math.exp(-z))将每个节点的值统一到0-1之间,再逐层向前计算直到输出层,对于输出层,实际上是不需要再用S函数的,我们这里将输出结果视为0到1之间的概率值,所以也采用了S函数,这样也有利于程序实现的统一性。

3. 反向修改权重

神经网络如何计算误差,一般采用平方型误差函数E,如下:

图片描述

也就是将多个输出项和对应目标值的误差的平方累加起来,再除以2。实际上逻辑回归的误差函数也是这个,至于为什么要用这个函数来计算误差,它从数学上的合理性是什么,怎么得来的,这个我建议程序员们不想当数学家的话,先不去深究了,现在我们要做的是如何把这个函数E误差取它的最小值,需要对其进行求导,如果有些求导数学基础的话,倒可以尝试去推导下如何从函数E对权重求导得到下面这个公式的:

图片描述

不会推导也没有关系,我们只需要运用结果公式就可以了,在我们的程序里用layerErr记录了E对权重求导后的最小化误差,再根据最小化误差去调整权重。

注意这里采用动量法调整,将上一次调整的经验考虑进来,避免陷入局部最小值,下面的k代表迭代次数,mobp为动量项,rate为学习步长:

Δw(k+1) = mobp*Δw(k)+rate*Err*Layer
也有很多使用下面的公式,效果上的差别不是太大:

Δw(k+1) = mobp*Δw(k)+(1-mobp)rate*Err*Layer
为了提升性能,注意程序实现是在一个while里面同时计算误差和调整权重,先将位置定位到倒数第二层(也就是最后一层隐含层)上,然后逐层反向调整,根据L+1层算好的误差来调整L层的权重,同时计算好L层的误差,用于下一次循环到L-1层时计算权重,以此循环下去直到倒数第一层(输入层)结束。

小结

在整个计算过程中,节点的值是每次计算都在变化的,不需要保存,而权重参数和误差参数是需要保存的,需要为下一次迭代提供支持,因此,如果我们构思一个分布式的多机并行计算方案,就能理解其他框架中为什么会有一个Parameter Server的概念。

多层神经网络完整程序实现

下面的实现程序BpDeep.java可以直接拿去使用,也很容易修改为C、C#、Python等其他任何语言实现,因为都是使用的基本语句,没有用到其他Java库(除了Random函数)。以下为原创程序,转载引用时请注明作者和出处。

import java.util.Random;
public class BpDeep{
    public double[][] layer;//神经网络各层节点
    public double[][] layerErr;//神经网络各节点误差
    public double[][][] layer_weight;//各层节点权重
    public double[][][] layer_weight_delta;//各层节点权重动量
    public double mobp;//动量系数
    public double rate;//学习系数

    public BpDeep(int[] layernum, double rate, double mobp){
        this.mobp = mobp;
        this.rate = rate;
        layer = new double[layernum.length][];
        layerErr = new double[layernum.length][];
        layer_weight = new double[layernum.length][][];
        layer_weight_delta = new double[layernum.length][][];
        Random random = new Random();
        for(int l=0;l<layernum.length;l++){
            layer[l]=new double[layernum[l]];
            layerErr[l]=new double[layernum[l]];
            if(l+1<layernum.length){
                layer_weight[l]=new double[layernum[l]+1][layernum[l+1]];
                layer_weight_delta[l]=new double[layernum[l]+1][layernum[l+1]];
                for(int j=0;j<layernum[l]+1;j++)
                    for(int i=0;i<layernum[l+1];i++)
                        layer_weight[l][j][i]=random.nextDouble();//随机初始化权重
            }   
        }
    }
    //逐层向前计算输出
    public double[] computeOut(double[] in){
        for(int l=1;l<layer.length;l++){
            for(int j=0;j<layer[l].length;j++){
                double z=layer_weight[l-1][layer[l-1].length][j];
                for(int i=0;i<layer[l-1].length;i++){
                    layer[l-1][i]=l==1?in[i]:layer[l-1][i];
                    z+=layer_weight[l-1][i][j]*layer[l-1][i];
                }
                layer[l][j]=1/(1+Math.exp(-z));
            }
        }
        return layer[layer.length-1];
    }
    //逐层反向计算误差并修改权重
    public void updateWeight(double[] tar){
        int l=layer.length-1;
        for(int j=0;j<layerErr[l].length;j++)
            layerErr[l][j]=layer[l][j]*(1-layer[l][j])*(tar[j]-layer[l][j]);

        while(l-->0){
            for(int j=0;j<layerErr[l].length;j++){
                double z = 0.0;
                for(int i=0;i<layerErr[l+1].length;i++){
                    z=z+l>0?layerErr[l+1][i]*layer_weight[l][j][i]:0;
                    layer_weight_delta[l][j][i]= mobp*layer_weight_delta[l][j][i]+rate*layerErr[l+1][i]*layer[l][j];//隐含层动量调整
                    layer_weight[l][j][i]+=layer_weight_delta[l][j][i];//隐含层权重调整
                    if(j==layerErr[l].length-1){
                        layer_weight_delta[l][j+1][i]= mobp*layer_weight_delta[l][j+1][i]+rate*layerErr[l+1][i];//截距动量调整
                        layer_weight[l][j+1][i]+=layer_weight_delta[l][j+1][i];//截距权重调整
                    }
                }
                layerErr[l][j]=z*layer[l][j]*(1-layer[l][j]);//记录误差
            }
        }
    }

    public void train(double[] in, double[] tar){
        double[] out = computeOut(in);
        updateWeight(tar);
    }
}

一个运用神经网络的例子

最后我们找个简单例子来看看神经网络神奇的效果。为了方便观察数据分布,我们选用一个二维坐标的数据,下面共有4个数据,方块代表数据的类型为1,三角代表数据的类型为0,可以看到属于方块类型的数据有(1,2)和(2,1),属于三角类型的数据有(1,1),(2,2),现在问题是需要在平面上将4个数据分成1和0两类,并以此来预测新的数据的类型。

图片描述

我们可以运用逻辑回归算法来解决上面的分类问题,但是逻辑回归得到一个线性的直线做为分界线,可以看到上面的红线无论怎么摆放,总是有一个样本被错误地划分到不同类型中,所以对于上面的数据,仅仅一条直线不能很正确地划分他们的分类,如果我们运用神经网络算法,可以得到下图的分类效果,相当于多条直线求并集来划分空间,这样准确性更高。

图片描述

下面是这个测试程序BpDeepTest.java的源码:

import java.util.Arrays;
public class BpDeepTest{
    public static void main(String[] args){
        //初始化神经网络的基本配置
        //第一个参数是一个整型数组,表示神经网络的层数和每层节点数,比如{3,10,10,10,10,2}表示输入层是3个节点,输出层是2个节点,中间有4层隐含层,每层10个节点
        //第二个参数是学习步长,第三个参数是动量系数
        BpDeep bp = new BpDeep(new int[]{2,10,2}, 0.15, 0.8);

        //设置样本数据,对应上面的4个二维坐标数据
        double[][] data = new double[][]{{1,2},{2,2},{1,1},{2,1}};
        //设置目标数据,对应4个坐标数据的分类
        double[][] target = new double[][]{{1,0},{0,1},{0,1},{1,0}};

        //迭代训练5000次
        for(int n=0;n<5000;n++)
            for(int i=0;i<data.length;i++)
                bp.train(data[i], target[i]);

        //根据训练结果来检验样本数据
        for(int j=0;j<data.length;j++){
            double[] result = bp.computeOut(data[j]);
            System.out.println(Arrays.toString(data[j])+":"+Arrays.toString(result));
        }

        //根据训练结果来预测一条新数据的分类
        double[] x = new double[]{3,1};
        double[] result = bp.computeOut(x);
        System.out.println(Arrays.toString(x)+":"+Arrays.toString(result));
    }
}

小结

以上测试程序显示神经网络有很神奇的分类效果,实际上神经网络有一定优势,但也不是接近人脑的万能算法,很多时候它可能会让我们失望,还需要结合各种场景的数据大量运用去观察其效果。我们可以把1层隐含层改成n层,并调整每层节点数、迭代次数、学习步长和动量系数,以获得一个最优化的结果。但是很多时候n层隐含层的效果并不比1层有明显提升,反而计算更复杂耗时,我们对神经网络的认识还需要多实践多体会。

ZRender 一个实用的js图形库

Architecture

MVC核心封装实现图形仓库、视图渲染和交互控制:

  • Stroage(M) : shape数据CURD管理
  • Painter(V) : canvase元素生命周期管理,视图渲染,绘画,更新控制
  • Handler(C) : 事件交互处理,实现完整dom事件模拟封装
  • shape : 图形实体,分而治之的图形策略,可定义扩展
  • tool : 绘画扩展相关实用方法,工具及脚手架
  • animation : 动画扩展,提供promise式的动画接口和常用缓动函数

APACHE如何在一个站点绑定多个域名?

<VirtualHost *:80>
ServerAdmin i@test.com
DocumentRoot /www/test.com
ServerName www.test.com
</VirtualHost>

<VirtualHost *:80>
ServerAdmin i@test2.com
DocumentRoot /www/test2.com
ServerName www.test2.com
</VirtualHost>

<VirtualHost *:80>
ServerAdmin i@test3.com
DocumentRoot /www/test3.com
ServerName www.test3.com
</VirtualHost>