精华内容
下载资源
问答
  • 操作word读写或者向word中插入图片实现,经大量搜索贴子,发现基本思路是明白了(用com对象操作),但是例子代码太少,同时有的代码写法不够严谨或者使用模块等,导致实现效果理想,也容易理解.因此开贴,给新人及我等...
  • Imperfect C++ word 中文

    2011-11-17 13:25:20
    也不乏许多作者创新、你从未听说过或使用技术,但这些确实帮助你成为c++方面专家。..  本书适合一定经验c++程序员和项目经理阅读,也适合对c++编程一些专门或高级话题感兴趣读者参考。  本书...
  • "这能在Word中做到吗?Powerpoint能做到吗?能不能用调制解调器拨号到远程服务器上并发布数据?Java无法实现这些功能是什么意思啊?Java可以实现任何功能。"  感谢作为Java和COM桥梁框架组件,它使你在遇到这些...
  • 用Delphi实现Word文件预览

    热门讨论 2005-07-13 15:37:57
    如果我们创建一个 Line2D.Double 对象代表线,创建一个 Ellipse2D.Double 对象代表圆,那么我们就可以通过移动用户坐标系和画这两个对象的一个或其它的对象而画出整个图像。 如果是按真正面向对象的方法,应该...
  • word使用技巧大全

    热门讨论 2011-03-18 20:37:53
    本资源是本人在攥写论文时,收集、整理,期望对广大同仁有所帮助! 内容主要包括: word使用技巧;公式编辑技巧;页眉页脚技巧;目录处理技巧;参考文献格式排版技巧,word画图技巧,word转...9.在Word中插入当前...
  • Word域教程.pdf

    2013-10-16 01:31:07
    根据经验,只要在Word中善于使用“域”,并结合Windows“剪贴板”,就快速、方便、简捷地录入各种公式。 要使用域,我们必须知道什么是域?域是一种特殊代码,用来指导WORD在文档中自动插入文字、图形、页码和...
  • PLSQL基础word

    2011-12-09 12:30:06
    PL/SQL是一种高性能的基于事务处理的语言,运行任何ORACLE环境,支持所有数据处理命令。通过使用PL/SQL程序单元处理SQL的数据定义和数据控制元素。  . PL/SQL支持所有SQL数据类型和所有SQL函数,同时支持...
  • 正是因为微博拥有这些特征,很多正面或者负面新闻不能通过传统媒体报道却能通过微博途径大肆传播。随着新浪微博发展与推广,越来越多人喜欢将自己生活“曝光”微博上,例如心情状态、将来计划、晒一晒生活...
  • 平时我们所使用的word,ppt 等文档都是先从硬盘里面加载到内存里才显示,所以如果文件比较大话我们会发现加载速度会有些慢,world加载完后我们可以进行任意修改,因为我们是内存之修改后保存到硬盘...
    平时我们所使用的word,ppt 等的文档都是先从硬盘里面加载到内存里才显示,所以如果文件比较大的话我们会发现加载的速度会有些慢,world中加载完后我们可以进行任意的修改,因为我们是在内存之中修改后保存到硬盘的,但是硬盘里面的东西是不能随意修改的,因为每一个存储的对象都有一个唯一的地址。

    我们在修改内容的方式可以采用牺牲硬盘或是牺牲内存两种方式来实现,以上world,ppt方式就是以牺牲内存的方式实现修改,牺牲硬盘是指新建一个空间,然后程序到原有的内容去循环然后找到需要修改的内容,替换之后存储到新的空间里面。

    一、牺牲硬盘的形式修改:
    #文件的修改
    import os
    f_file = 'C:/Users/jeep-peng zhang/Desktop/22.txt'
    f_new_file ='%s.new.txt' %f_file#创建新的地方
    f = open(f_file,'r',encoding='gbk')
    f_new = open(f_new_file,'w',encoding='gbk')
    old_str ="计算机二级"
    new_str = "洛天诚巨白"
    
    for line in f:
        if old_str in line:#判断是否在这行
            line = line.replace(old_str,new_str)
        f_new.write(line)
    f.close()
    f_new.close()
    os.rename(f_new_file,f_file)#window路径下会出错需修改路径不显示模式

     二、牺牲内存形式修改:

    file = 'C:/Users/jeep-peng zhang/Desktop/22.txt'
    f = open(file,'r+',encoding='gbk')
    date = f.read() #加载到内存里
    f.seek(0)#回到最开始
    new_date = date.replace('计算机二级','我是买包888的小行家')#替换
    f.write(new_date)

    后面可以使用f.truncate()从当前位置截断。

    
    
    
    


    转载于:https://www.cnblogs.com/jeepzp/p/8228882.html

    展开全文
  • BOM浏览器对象模型

    2020-01-03 19:59:39
    虚拟机:任何语言编辑程序都需要一个虚拟机来执行,如果脱离这个环境就不能执行。 运行时(runtime):百度解释为 虚拟机一种,一般指进程级别虚拟机。运行过程不断地处理程序。 同一款浏览器不同系统...

    前言

    • 任何文件都需要使用特定的方式打开,比如 .doc文件需要word、WPS来打开。
    • 虚拟机:任何语言编辑的程序都需要一个虚拟机来执行,如果脱离这个环境就不能执行。
    • 运行时(runtime):百度解释为 虚拟机的一种,一般指进程级别的虚拟机。在运行过程中不断地处理程序。
    • 同一款浏览器在不同的系统中,属性值是不同的。
    • 在同一个系统中,不同的浏览器,属性都有不同。
    • BOM是有兼容性问题,DOM也是有兼容问题的。
    • ECMAScript 这个是属于各浏览器完全兼容的,只不过版本过低的浏览器不支持ES6以上。
    • chrome浏览器的引擎是V8引擎,针对 JavaScript 开发的引擎,使用C++来开发。

    BOM 树型结构

    Browser Object Model 浏览器对象模型
    BOM的根是window

    BOM的对象

    • window.documnet 文档
    • window.location 本地信息
    • window.history 历史
    • window.screen 浏览器所在的屏幕
    • window.navigator 浏览器的信息
    window对象
    • open()
    • close()
    • innerHeight、innerWidth
    • outerheight、outerWidth
    • screenLeft、screenTop
    • screenX、screenY
    //window.alert("aa");
    //var a=5;
    //window.a;
    //this
    open("http://www.163.com)","网易","width:300,height=300;);//弹窗,现在基本被拦截,基本不用
    document.onclick=function(){
        close();//关闭窗口
    }
    
    console.log(innerWidth;innerHeight);//浏览器可视文档窗口的宽度和高度,包含滚动条宽度
    console.log(outerWidth,outerHeight);//如果是全屏,宽度和上面相同,如果不是全屏,宽度就包含阴影宽度;整个浏览器的高度
    //以下两个值都表示浏览器窗口距离屏幕左上顶点的距离,只读数据
    console.log(screenLeft,screenTop);
    console.log(screenX,screenY);
    
    location对象
    • location.reload() 重载页面
    • location.href、location.assign()、location.replace() 页面跳转
    • location.hash 获取url中#后的字符串,如果没有,则返回空字符串。
    • location.search 获取url中?后的字符串,如果没有,则返回空字符串。
    • location.hostname 返回 web 主机的域名
    • location.pathname 返回当前页面的路径和文件名
    • location.port 返回web 主机的端口 (80 或 443)
    • location.protocol 返回所使用的 web 协议(http:// 或 https://)
    //重载刷新当前页面
    location.reload();
    //location.href 除了可以设置跳转,也可以获取当前页面的地址,可以产生历史记录
    location.href="http://www.baidu.com";
    //location.assign()只能设置跳转,可以产生历史记录
    location.assign("http://www.baidu.com");
    //location.replace()替换当前页面的地址,不能产生历史记录
    location.replace("http://www.baidu.com");
    //获取url中#后的字符串,如果没有,则返回空字符串。 
    console.log(location.hash);
    //获取url中?后的字符串,如果没有,则返回空字符串。 
    console.log(location.search);
    //返回 web 主机的域名
    console.log(location.hostname);
    //返回当前页面的路径和文件名 
    console.log(location.pathname);
    //返回 web 主机的端口 (80 或 443)
    console.log(location.port);
    //返回所使用的 web 协议(http:// 或 https://)
    console.log(location.protocol);
    
    history对象
    • history.back 向后退一页
    • history.forward 向前进一页
    • history.go(0) 刷新页面
    • history.go(-1) 向后退一页
    • history.go(1) 向前进一页
    • history.go(2) 向前进两页
    • history.length 属性返回历史列表中的网址数
    history.back;//向后退一页
    history.forward;//向前进一页
    history.go(0);//刷新页面
    history.go(-1);//向后退一页
    history.go(1);//向前进一页
    history.go(2);//向前进两页
    history.length;//属性返回历史列表中的网址数
    
    screen对象
    • screen.availHeight,screen.availWidth 电脑屏幕的宽高像素减去系统部件宽高之后的值
    • screen.height,screen.width 电脑屏幕的高度和宽度
    //电脑屏幕的宽高像素减去系统部件宽高之后的值
    console.log(screen.availHeight,screen.availWidth);
    //电脑屏幕的高度和宽度
    console.log(screen.height,screen.width);
    
    navigator对象
    • navigator.userAgent 返回由客户机发送服务器的 user-agent 头部的值
    • navigator.appName 返回浏览器的名称。
    • navigator.appVersion 返回浏览器的平台和版本信息。
    • navigator.platform 返回运行浏览器的操作系统平台。
    console.log(navigator.userAgent);//返回由客户机发送服务器的 user-agent 头部的值
    //Firefox打印出 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
    //chrome打印出  Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
    //360安全浏览器 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
    
    console.log(navigator.appName);//返回浏览器的名称。
    //Firefox打印出  Netscape
    //chrome打印出   Netscape
    //360安全浏览器  Netscape
    
    console.log(navigator.appVersion);//返回浏览器的平台和版本信息。
    //Firefox打印出   5.0(windows)
    //chrome打印出    5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
    //360安全浏览器   5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
    
    console.log(navigator.platform);//返回运行浏览器的操作系统平台。
    //Firefox打印出  Win32
    //chrome打印出   Win32
    //360安全浏览器  Win32
    
    展开全文
  • 而且不能删除当前用户,如果删除用户数据对象,那么必须加上关键字cascade。 用法:drop user 用户名 [cascade] 四、 用户权限与角色 1. 权限 Oracle权限主要分为两种,系统权限和实体权限。  系统权限:...
  • 唯一无二的对象模式让您可以文档自由放置图像、绘图和文本。实时文字统计让你随时关注所需长度,原生支持 DOCX 让您的文档可以与 Microsoft Word 无缝衔接工作。编写完成的文档可以打印出来或是导出为 PDF 及...
  • 您再也不必担心文件格式的兼容性:用Word 97、写字板或过去版本的WPS 处理的文件,WPS 2000 都很好地读入,最大程度地保护您的利益。 以往的WPS 着重处理文字,而现在的WPS 2000 极大地丰富了文字处理软件的内涵,...
  • 企业网站英文

    2012-11-30 20:30:17
    3.修改了新闻评论英文不能自己动换行错误; 4.修正了产品编号长度不够问题; 5.企业简介栏目自动生成; 6.新闻资讯分类自动生成,后台更改新闻类别,前台新闻分类自动生成; 7.完善下载说明详细信息; 8.所有...
  • 由于光盘容量有限,笔者删除了原始镜像目录一部分网页,可能执行效果和书上不能完全一致,请读者读懂原理后灵活处理。 说明:因为mirror.rar文件引用了第三方网站大量信息,这需要得到网站授权,授权办理...
  • 由于光盘容量有限,笔者删除了原始镜像目录一部分网页,可能执行效果和书上不能完全一致,请读者读懂原理后灵活处理。 说明:因为mirror.rar文件引用了第三方网站大量信息,这需要得到网站授权,授权办理...
  • 由于光盘容量有限,笔者删除了原始镜像目录一部分网页,可能执行效果和书上不能完全一致,请读者读懂原理后灵活处理。 说明:因为mirror.rar文件引用了第三方网站大量信息,这需要得到网站授权,授权办理...
  • Toxy高级扩展功能Toxy除了提供基础的抽取功能,也提供一些高级的对象转换服务,比如ToxySpreadsheet转DataSet,可以直接把Excel的数据转换成DataSet,方便调用和处理。代码超级简单,如下所示:1234ParserContext c=...
  • 在word的编辑状态,执行编辑命令“粘贴”后____ A.将文档被选择内容复制到当前插入点处 B.将文档被选择内容移到剪贴板 C.将剪贴板中的内容移到当前插入点处 D.将剪贴板中的内容拷贝到当前插入点处 D 2 下面...
  • 第四课.词向量

    2020-11-09 17:30:21
    词向量:我希望将单词word转为一个vector,因为机器不能直接感知到人类所说语言,只有将单词转换为数值对象才能进行后续处理早期NLP领域,单词编码使用one-hot,这样编码只是为了区分各个词,完全没有...

    词向量发展

    在自然语言处理问题中,会涉及到一个重要部分:词向量;
    词向量:我希望将单词word转为一个vector,因为机器不能直接感知到人类所说的语言,只有将单词转换为数值对象才能进行后续处理;
    在早期NLP领域,单词的编码使用one-hot,这样的编码只是为了区分各个词,完全没有语义信息;
    后来出现了TF-IDF,为每个word增加权重信息,常见的word权重大,罕见的word权重小,这样处理后,稍微看到了一点语义信息;
    单词的编码还需要包含相似性,比如美洲豹和剑齿虎的编码在欧氏空间应该有较近的距离:
    fig1
    伴随着这样的思考,诞生了分布式表示(Distributed Representation):用一个词附近的词表示该词,这个想法是NLP的重大转折点,比如之后出现了word2vec(CBOW和Skip-Gram),CBOW可以理解为用周围的词预测中间的词,Skip-Gram可以理解为用中间的词预测周围的词,在paper中,也指出了Skip-Gram的效果更好

    Skip-Gram

    首先需要明白,词向量本身只是一个矩阵,对于同样的词汇表和同样的目标任务,不管是CBOW还是Skip-Gram,它们训练出来的词向量都是一个同样形状的二维张量,唯一不同在于其训练的方式;


    关于词向量如何将单词编码
    需要让输入的单词都是one-hot编码的形式,假设词汇表的单词数量为3000,则表中某个词bird将编码为[0,0,0,1,0,...,0],该向量中只有一个1,其余都是0,共3000位元素,bird的one-hot编码形状为[1,3000];
    如果要将编码压缩为100个元素的向量,词向量形状则为[3000,100],当bird的one-hot编码与词向量相乘,就得到bird的向量[1,100],这个向量携带了一定的语义信息,准确来说,[1,100]这个向量才是词向量;
    之前的二维张量叫做词向量也是有原因的,编码bird的过程等价于从张量索取了bird对应的行,所以这个二维张量相当于是词汇表中所有单词的编码集合


    前面说过,Skip-Gram可以理解为用中间的词预测周围的词,根据Distributed Representation可以理解,其本质应该是中心词与周围词的关系更密切,这种关系被形象地可视化为:
    fig2
    projection并不是一个线性变换,而是指投影,即已编码的中心词w(t)与已编码的周围词w(t+i)投影相乘,结果越大,代表关系越紧密;
    另外一提,Skip-Gram本身(对中心词和周围词编码,再投影)并没有意义,但通过Skip-Gram这种方式来训练,可以得到一个好的词向量;
    Skip-Gram具体实现过程
    词向量的训练实际上属于无监督学习,Skip-Gram需要两个同样shape的二维张量,一个用于编码中心词,另一个用于编码所有在词汇表内的词;
    不能共用二维张量的原因:所谓中心词与周围词关系密切不能在同一编码方式下投影,比如"I like NLP",同一种编码下,很难让机器看出like与I和NLP相似;
    令中心词编码后的向量为vcv_{c},某个周围词编码后的向量为uou_{o},词汇表内各个词编码后的向量uwu_{w},编码用到两个张量embed1和embed2,注意,vcv_{c}通过张量embed1编码,uou_{o}uwu_{w}都是通过embed2编码,词汇表共WW个单词;
    则基于softmax可以求出相似度的概率表达:
    p(uovc)=exp(uoTvc)w=1Wexp(uwTvc)p(u_{o}|v_{c})=\frac{exp(u_{o}^{T}v_{c})}{\sum_{w=1}^{W}exp(u_{w}^{T}v_{c})}
    可以看出,中心词与周围词越相似,则输出概率值越大,Skip-Gram要用中心词与在窗口内的所有周围词计算相似度,假设窗口内前后各有cc个词,随机从语料库选择TT个中心词,则训练目标为:
    min1Tt=1Tcjc,j0log(p(wt+jwt))min-\frac{1}{T}\sum_{t=1}^{T}\sum_{-c\leqslant j\leqslant c,j\neq 0}^{}log(p(w_{t+j}|w_{t}))
    p(wt+jwt)p(w_{t+j}|w_{t})取对数可以将连乘转为累加,避免反向传播计算梯度时出现梯度消失现象;
    在上述计算中,softmax分母计算量很大,vcv_{c}要与每个word的编码求点积,为了加速计算,改进出简化版本,核心做法在于随机从词汇表中选出负例样本,计算规模得到缩减,softmax也改成sigmoid函数:
    p(uoTvc)=11+exp(uoTvc)p(u_{o}^{T}v_{c})=\frac{1}{1+exp(-u_{o}^{T}v_{c})}
    假设从词汇表随机采样KK个单词的编码uku_{k}作为负样本,则训练目标改写为:
    minlog(p(uoTvc))+k=1Klog(p(ukTvc))min-log(p(u_{o}^{T}v_{c}))+\sum_{k=1}^{K}log(p(u_{k}^{T}v_{c}))
    上式希望中心词与周围词越紧密越好,与随机采样的负样本关系越疏远越好;
    注意一个细节,sigmoid函数将值映射到0-1之间,但log(0->1)的值是小于零的,所以k=1Klog(p(ukTvc))\sum_{k=1}^{K}log(p(u_{k}^{T}v_{c}))会是负值且绝对值较大,log(p(uoTvc))-log(p(u_{o}^{T}v_{c}))虽是正值,但比较小,最终的目标值将会小于零,这对人类视角看待最小化问题有一些别扭,所以,根据sigmoid的单调性,目标改写为:
    min[log(p(uoTvc))+k=1Klog(p(ukTvc))]min-[log(p(u_{o}^{T}v_{c}))+\sum_{k=1}^{K}log(p(-u_{k}^{T}v_{c}))]
    这样一来,目标值将必然大于零,所以最小化的结果越接近零越好;接下来,我将根据这个负采样的做法实现Skip-Gram训练,通过反向传播的梯度更新张量embed1和embed2,最后取出embed1即词向量

    Pytorch实现Skip-Gram

    随机种子和超参数设置

    为了使实验可以复现,设置随机种子,并固定超参数:

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    from collections import Counter#统计单词出现次数
    import numpy as np
    
    #为了确保实验可以复现,设置随机种子
    import random
    
    #都设置一遍随机种子
    random.seed(53113)
    np.random.seed(53113)
    torch.manual_seed(53113)
    
    USE_CUDA=torch.cuda.is_available()
    
    if USE_CUDA:
        #GPU也设置随机种子
        torch.cuda.manual_seed(53113)
        
    #设置超参数hyper parameters
    C=3 #context window
    K=100 #负例采样数量
    NUM_EPOCHS=1
    MAX_VOCAB_SIZE=30000 #英语中,有3万个常见单词
    BATCH_SIZE=128
    LEARNING_RATE=0.2
    EMBEDDING_SIZE=100
    

    语料处理

    首先获取文本组成的语料数据,确保已删除所有标点符号,单词用空格分开,然后可以用split()分词得到字符串列表:

    #用于对语料数据进行分词
    def word_tokenize(text):
        #S.split(sep=None, maxsplit=-1) -> list of strings
        #split的seq默认为所有空字符
        return text.split()
    

    下一步创建单词表vocab{word:counts},vocab设置容量3万个单词MAX_VOCAB_SIZE=30000(英语常用单词有3万个),在这3万个单词中,有一个比较特殊:用于代表语料库中所有不常见单词,记为"<unk>";
    一般训练一个良好的词向量需要超大的数据,我的小数据集效果应该不会太好,注意:这个数据集已经去除过所有标点符号;
    分词获取列表:

    with open("./DataSet/textset/texttrain.txt","r") as f:
        text=f.read()
    
    #对语料进行分词
    text=word_tokenize(text.lower())
    

    借助from collections import Counter统计单词出现次数:

    #统计词数,len(Counter(text).keys()) 远大于 MAX_VOCAB_SIZE
    vocab=dict(Counter(text).most_common(MAX_VOCAB_SIZE-1))
    
    #最后一个统一为UNK
    vocab["<unk>"]=len(text)-np.sum(list(vocab.values()))
    

    构建mapping,为词建立序号,以便于one-hot编码:

    #构建mapping,为词建立序号,以便于one-hot编码
    idx_to_word=[word for word in vocab.keys()]
    word_to_idx={word:i for i,word in enumerate(idx_to_word)}
    

    获取词频,用于后续训练的采样:

    #计算词频率
    word_counts=np.array([count for count in vocab.values()],dtype=np.float32)
    word_freqs=word_counts/np.sum(word_counts)
    
    #word2vec论文中增加了一个细节
    word_freqs=word_freqs**(3./4.)
    word_freqs=word_freqs/np.sum(word_freqs)
    

    注意:word_to_idx,idx_to_word,word_freqs,word_counts的顺序都是一致对应的

    使用dataloader

    dataloader是pytorch中的数据加载器,用于高效生成训练需要的batch data,在使用dataloader前,先定义dataset,一般流程为:实现dataset对象,用dataloader封装dataset产生batch

    实现Dataset对象

    dataset继承自torch.utils.data.Dataset,对于NLP的简单任务,至少需要在dataset类中完成三个魔法方法__init__(),__len__(),__getitem__();
    在本次实现中,dataset应该做到将text列表内的单词进行编码(基于word_to_idx),__getitem__()能够根据输入的index从经过编码的text返回一个中心词和2c2c个周围词,2cK2cK个负例词:

    import torch.utils.data as tud
    
    class WordEmbeddingDataset(tud.Dataset):
        # word_to_idx,idx_to_word,word_freqs,word_counts的顺序都是一致对应的
        def __init__(self,text,word_to_idx,idx_to_word,word_freqs,word_counts):
            super().__init__()
            #获得text的每个单词在word_to_idx中的序号,D.get(k[,d]) -> D[k] if k in D, else d.
            self.text_encoded=[word_to_idx.get(word,word_to_idx["<unk>"]) for word in text]      
            self.text_encoded=torch.tensor(self.text_encoded,dtype=torch.long)
            
            self.word_to_idx=word_to_idx
            self.idx_to_word=idx_to_word
            self.word_freqs=torch.tensor(word_freqs,dtype=torch.float)
        
        def __len__(self):
            #数据集的item数量
            #数据集就是text的每个词通过word_to_idx进行了编码
            return len(self.text_encoded)
        
        
        def __getitem__(self,location):
            #给一个词在text_encoded中的位置,返回一串训练数据(前后的词)
            center_word=self.text_encoded[location]
            #周围词在text_encoded中的位置,range左闭右开
            pos_indices=list(range(location-C,location))+list(range(location+1,location+C+1))
            #目前的pos_indices可能会超出text_encoded的边界,所以通过取余避免
            pos_indices=[i%len(self.text_encoded) for i in pos_indices]
            #类似于numpy的快速索引
            pos_words=self.text_encoded[pos_indices]
            
            #根据词出现的频率随机采样,借助torch.multinomial
            """
            torch.multinomial(input, num_samples, replacement=False,)->LongTensor
            replacement指的是取样时是否是有放回的取样
            返回的是input的索引组成的tensor
            """
            #由于word_freqs顺序与word_to_idx顺序一致,相当于采样返回的也是idx
            neg_words=torch.multinomial(self.word_freqs,K*pos_words.shape[0],replacement=True)
            
            return center_word,pos_words,neg_words
    
    
    dataset=WordEmbeddingDataset(text,word_to_idx,idx_to_word,word_freqs,word_counts)
    

    dataloader封装

    使用dataloader包装dataset,读取占用更少内存,高效产生batch:

    dataloader=tud.DataLoader(dataset,batch_size=BATCH_SIZE,shuffle=True,num_workers=4)
    

    定义模型

    首先明确:Embedding本质就是一个(vocab_size,embed_size)的tensor;
    按照前面的说明,此次Embedding层需要两个二维tensor,在前面所说的embed1命名为embed_in,embed2命名为embed_out,像第二课所说的,__init__()中定义要计算梯度的层,前向传播过程定义在forward内;
    本次实现新增一个实例方法get_weight,用于获取词向量embed_in;


    torch.nn.Embedding
    在nn中已经有Embedding层,输入并不需要真的转换到one-hot向量,而是像CrossEntropyLoss那样,使用了索引的方式计算,这也是为什么dataset类里的self.text_encoded元素类型为torch.long的原因;
    对于nn.Embedding(vocab_size,embed_size)
    Embedding的输入可以是一个在0到vocab_size-1之间的整数,输出是一个包含embed_size个元素的向量


    模型定义如下:

    class EmbeddingLayer(nn.Module):
        def __init__(self,vocab_size,embed_size):
            super().__init__()
            self.vocab_size=vocab_size
            self.embed_size=embed_size
            
            self.in_embed=nn.Embedding(self.vocab_size,self.embed_size,sparse=False)
            self.out_embed=nn.Embedding(self.vocab_size,self.embed_size,sparse=False)
            
            #对embedding层的权重进行初始化,使训练一开始的loss较小
            initrange=0.5/self.embed_size
            self.in_embed.weight.data.uniform_(-initrange,initrange)
            self.out_embed.weight.data.uniform_(-initrange,initrange)
            
            
        def forward(self,input_labels,pos_labels,neg_labels):
            # input_labels: [batch_size]
            # pos_labels: [batch_size,C*2]
            # neg_labels: [batch_size,C*2*K]
            
            #nn.Embedding的输入是一组索引列表
            input_embedding=self.in_embed(input_labels) #[batch_size, embed_size]
            pos_embedding=self.out_embed(pos_labels)   #[batch_size, C*2, embed_size]
            neg_embedding=self.out_embed(neg_labels)   #[batch_size, C*2*K, embed_size]
            
            #为了bmm,增加一个维度
            input_embedding=input_embedding.unsqueeze(2) #[batch_size, embed_size, 1]
            #批处理张量乘法bmm:batch matrix multiplication(b,m,n)*(b,n,p)->(b,m,p)
            pos_dot=torch.bmm(pos_embedding,input_embedding) #[batch_size, C*2, 1]
            #去除最后一个维度
            pos_dot=pos_dot.squeeze(2) #[batch_size,C*2]
            
            neg_dot=torch.bmm(neg_embedding,input_embedding).squeeze(2) #[batch_size,C*2*K]
            
            #顺便计算目标函数,借助logsigmoid,即log(sigmoid(value))
            log_pos=F.logsigmoid(pos_dot).sum(dim=1)
            log_neg=F.logsigmoid(-neg_dot).sum(dim=1)
            
            loss=-log_pos-log_neg
            
            return loss #[batch_size]
        
        def get_weight(self):
            #获取词向量层的权重,用于np保存数据
            return self.in_embed.weight.data.cpu().numpy()
    

    生成对象:

    # 模型实例化
    model=EmbeddingLayer(MAX_VOCAB_SIZE,EMBEDDING_SIZE)
    if USE_CUDA:
        model=model.cuda()
    

    训练

    基于dataloader,类似于keras中的生成器产生batch,可以方便的产生batch data,比如:

    for i,(input_labels,pos_labels,neg_labels) in enumerate(dataloader):
    

    选择优化方法并训练:

    optimizer=torch.optim.SGD(model.parameters(),lr=LEARNING_RATE)
    
    loss_embedding=[]
    for epoch in range(NUM_EPOCHS):
        for i,(input_labels,pos_labels,neg_labels) in enumerate(dataloader):
            #print(input_labels,pos_labels,neg_labels)
            input_labels=input_labels.long()
            pos_labels=pos_labels.long()
            neg_labels=neg_labels.long()
            
            if USE_CUDA:
                input_labels=input_labels.cuda()
                pos_labels=pos_labels.cuda()
                neg_labels=neg_labels.cuda()
            
            loss=model.forward(input_labels,pos_labels,neg_labels).mean()
            if i%100==0:
                print(epoch,i,loss.item())
                loss_embedding.append(loss.item())
            
            loss.backward()
            
            optimizer.step()
            
            model.zero_grad()
    

    定期将loss加入列表后,可视化训练过程为:

    #绘制学习曲线
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    plt.figure(figsize=(10,6))
    plt.subplot(1,1,1)
    #后面的loss基本变化微小,取0:300绘图,效果更好
    nploss=np.array(loss_embedding[:300])
    series=np.arange(len(nploss))
    plt.plot(series,nploss)
    plt.xlabel("series")
    plt.ylabel("loss")
    plt.title("learning cruve")
    plt.show()
    

    fig3
    在实际训练中,通常不会过度关注loss,而是看spearmanr是否在上升


    spearmanr:用模型计算人工词语的相似度,再与人工给出的相似度对比


    保存模型参数

    在定义模型时,可以通过方法get_weight()取出张量embed_in,我将用numpy的方式保存参数:

    #np保存模型的参数
    embedding_weights = model.get_weight()
    np.save("embedding-{}".format(EMBEDDING_SIZE),embedding_weights)
    

    也可以用torch保存参数,在保存时,需要明确保存的对象为model.state_dict()model.state_dict()是模型所有可学习的参数名与张量组成的字典:

    torch.save(model.state_dict(), "embedding-{}.th".format(EMBEDDING_SIZE))
    

    这样将会保存embed_in和embed_out,通过重新生成一个对象,并导入参数可验证:
    fig4

    展开全文
  • 虽然不是很难,但很多细小问题需要认真对待,稍有不注意问题就会具体应用程序调试过程出现,这要求我们实践过程除了要了塌实理论知识还要细心,耐心。当然本次设计过程还出现了其他不少...
  • 由于光盘容量有限,笔者删除了原始镜像目录一部分网页,可能执行效果和书上不能完全一致,请读者读懂原理后灵活处理。 <br>说明:因为mirror.rar文件引用了第三方网站大量信息,这需要得到网站授权,授权...
  • 实例047——创建完全只读(没有输入焦点,不能选择)编辑框 实例048——实现只能输入小数编辑框控件 实例049——使用Rich Edit编辑框格式化显示文本 实例050——设定静态文本框背景色和文本颜色 实例051...
  • 所有报表和基本资料均可导入EXCEL进行分析加工,以满足用户更高要求。 2。高效强大查询工具: 系统提供多种查询方式来帮助您快速找到所需要资料。无论是使用预制条件还是临时高级组合查找,都能够让...
  • 先放代码,遇到问题是 调用mysql**参**存储...如图,是要像这样处理一张表内容,单单用output参数是做,主要问题如果加参数这些东西是可以读出来,但是加了参数就获取到结果集了。。。。
  • 宏是AutoCAD VBA开发中一个最基础但又非常重要概念,而集合对象在开发过程使用非常频繁,必要学习开始阶段打下坚实基础。 第2章包括文档操作、缩放视图、命名视图,以及和用户交互操作。“文档操作”...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 227
精华内容 90
关键字:

在word中不能处理的对象有