精华内容
下载资源
问答
  • *如果可用sizeof()确定大小,就可以用malloc()创建一个临时字符串来存储并输出最大字符子段,代码会简化很多~! *不过如果用malloc()保存最大子段,随着最大子段变化,需要不停的free()再重新malloc(),要注意 *...
  • 传统上把数组(array)定义为一组有某种共同特性的元素,这里的共同特性包括相似性(车模、棒球队、水果类型等)和类型(例如所有元素都是字符串或整数)等,个元素由一个特殊的标识符来区分,这称为健(key)。...
  • 用数字表示文本 机器学习模型将向量(数字数组)作为输入。在处理文本时,我们必须先想出一种策略,将字符串...为了表示个单词,我们将创建一个长度等于词汇量的零向量,然后在与该单词对应的索引中放置一个 1。下.

    用数字表示文本

    机器学习模型将向量(数字数组)作为输入。在处理文本时,我们必须先想出一种策略,将字符串转换为数字(或将文本“向量化”),然后再其馈入模型。在本部分中,我们将探究实现这一目标的三种策略。

    独热编码

    作为第一个想法,我们可以对词汇表中的每个单词进行“独热”编码。考虑这样一句话:“The cat sat on the mat”。这句话中的词汇(或唯一单词)是(cat、mat、on、sat、the)。为了表示每个单词,我们将创建一个长度等于词汇量的零向量,然后在与该单词对应的索引中放置一个 1。下图显示了这种方法。

    为了创建一个包含句子编码的向量,我们可以将每个单词的独热向量连接起来。

    要点:这种方法效率低下。一个独热编码向量十分稀疏(这意味着大多数索引为零)。假设我们的词汇表中有 10,000 个单词。为了对每个单词进行独热编码,我们将创建一个其中 99.99% 的元素都为零的向量。

    用一个唯一的数字编码每个单词

    我们可以尝试的第二种方法是使用唯一的数字来编码每个单词。继续上面的示例,我们可以将 1 分配给“cat”,将 2 分配给“mat”,依此类推。然后,我们可以将句子“The cat sat on the mat”编码为一个密集向量,例如 [5, 1, 4, 3, 5, 2]。这种方法是高效的。现在,我们有了一个密集向量(所有元素均已满),而不是稀疏向量。

    但是,这种方法有两个缺点:

    整数编码是任意的(它不会捕获单词之间的任何关系)。

    对于要解释的模型而言,整数编码颇具挑战。例如,线性分类器针对每个特征学习一个权重。由于任何两个单词的相似性与其编码的相似性之间都没有关系,因此这种特征权重组合没有意义。

    单词嵌入向量

    单词嵌入向量为我们提供了一种使用高效、密集表示的方法,其中相似的单词具有相似的编码。重要的是,我们不必手动指定此编码。嵌入向量是浮点值的密集向量(向量的长度是您指定的参数)。它们是可以训练的参数(模型在训练过程中学习的权重,与模型学习密集层权重的方法相同),无需手动为嵌入向量指定值。8 维的单词嵌入向量(对于小型数据集)比较常见,而在处理大型数据集时最多可达 1024 维。维度更高的嵌入向量可以捕获单词之间的细粒度关系,但需要更多的数据来学习。

    上面是一个单词嵌入向量的示意图。每个单词都表示为浮点值的 4 维向量。还可以将嵌入向量视为“查找表”。学习完这些权重后,我们可以通过在表中查找对应的密集向量来编码每个单词。


    下面来看看代码

    import io
    import os
    import re
    import shutil
    import string
    import tensorflow as tf
    
    from datetime import datetime
    from tensorflow.keras import Model, Sequential
    from tensorflow.keras.layers import Activation, Dense, Embedding, GlobalAveragePooling1D
    from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
    
    print(tf.__version__)
    """
    输出:2.5.0-dev20201226
    """
    

    下载IMDB数据集

    url = "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"
    
    dataset = tf.keras.utils.get_file("aclImdb_v1.tar.gz", url,
                                        untar=True, cache_dir='.',
                                        cache_subdir='')
    
    dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')
    os.listdir(dataset_dir)
    """
    输出:
    Downloading data from https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
    84131840/84125825 [==============================] - 138s 2us/step
    ['imdb.vocab', 'imdbEr.txt', 'README', 'test', 'train']
    """
    

    train文件夹中有pos与neg两个关于电影评论的文件夹,其中数据分别被标记为positive与negative,你可以使用这两个文件夹中的数据去训练一个二元分类模型

    train_dir = os.path.join(dataset_dir, 'train')
    os.listdir(train_dir)
    """
    输出:
    ['labeledBow.feat',
     'neg',
     'pos',
     'unsup',
     'unsupBow.feat',
     'urls_neg.txt',
     'urls_pos.txt',
     'urls_unsup.txt']
    """
    

    在创建数据集之前应该先移除多余的文件夹,例如unsup

    remove_dir = os.path.join(train_dir, 'unsup')
    shutil.rmtree(remove_dir)
    

    下一步,用tf.keras.preprocessing.text_dataset_from_directory函数创建一个tf.data.Dataset。用train文件夹中数据创建train与validation数据集,validation所占比例为20%(即validation_split为0.2)

    batch_size = 1024
    seed = 123
    train_ds = tf.keras.preprocessing.text_dataset_from_directory(
        'aclImdb/train', batch_size=batch_size, validation_split=0.2, 
        subset='training', seed=seed)
    val_ds = tf.keras.preprocessing.text_dataset_from_directory(
        'aclImdb/train', batch_size=batch_size, validation_split=0.2, 
        subset='validation', seed=seed)
    """
    输出:
    Found 25000 files belonging to 2 classes.
    Using 20000 files for training.
    Found 25000 files belonging to 2 classes.
    Using 5000 files for validation.
    """
    

    检查数据集中的评论数据以及对应的标签

    for text_batch, label_batch in train_ds.take(1):
        for i in range(5):
            print(label_batch[i].numpy(), text_batch.numpy()[i])
    """
    输出:
    0 b"Oh My God! Please, for the love of all that is holy, Do Not Watch This Movie! It it 82 minutes of my life I will never get back. Sure, I could have stopped watching half way through. But I thought it might get better. It Didn't. Anyone who actually enjoyed this movie is one seriously sick and twisted individual. No wonder us Australians/New Zealanders have a terrible reputation when it comes to making movies. Everything about this movie is horrible, from the acting to the editing. I don't even normally write reviews on here, but in this case I'll make an exception. I only wish someone had of warned me before I hired this catastrophe"
    1 b'This movie is SOOOO funny!!! The acting is WONDERFUL, the Ramones are sexy, the jokes are subtle, and the plot is just what every high schooler dreams of doing to his/her school. I absolutely loved the soundtrack as well as the carefully placed cynicism. If you like monty python, You will love this film. This movie is a tad bit "grease"esk (without all the annoying songs). The songs that are sung are likable; you might even find yourself singing these songs once the movie is through. This musical ranks number two in musicals to me (second next to the blues brothers). But please, do not think of it as a musical per say; seeing as how the songs are so likable, it is hard to tell a carefully choreographed scene is taking place. I think of this movie as more of a comedy with undertones of romance. You will be reminded of what it was like to be a rebellious teenager; needless to say, you will be reminiscing of your old high school days after seeing this film. Highly recommended for both the family (since it is a very youthful but also for adults since there are many jokes that are funnier with age and experience.'
    0 b"Alex D. Linz replaces Macaulay Culkin as the central figure in the third movie in the Home Alone empire. Four industrial spies acquire a missile guidance system computer chip and smuggle it through an airport inside a remote controlled toy car. Because of baggage confusion, grouchy Mrs. Hess (Marian Seldes) gets the car. She gives it to her neighbor, Alex (Linz), just before the spies turn up. The spies rent a house in order to burglarize each house in the neighborhood until they locate the car. Home alone with the chicken pox, Alex calls 911 each time he spots a theft in progress, but the spies always manage to elude the police while Alex is accused of making prank calls. The spies finally turn their attentions toward Alex, unaware that he has rigged devices to cleverly booby-trap his entire house. Home Alone 3 wasn't horrible, but probably shouldn't have been made, you can't just replace Macauley Culkin, Joe Pesci, or Daniel Stern. Home Alone 3 had some funny parts, but I don't like when characters are changed in a movie series, view at own risk."
    0 b"There's a good movie lurking here, but this isn't it. The basic idea is good: to explore the moral issues that would face a group of young survivors of the apocalypse. But the logic is so muddled that it's impossible to get involved.<br /><br />For example, our four heroes are (understandably) paranoid about catching the mysterious airborne contagion that's wiped out virtually all of mankind. Yet they wear surgical masks some times, not others. Some times they're fanatical about wiping down with bleach any area touched by an infected person. Other times, they seem completely unconcerned.<br /><br />Worse, after apparently surviving some weeks or months in this new kill-or-be-killed world, these people constantly behave like total newbs. They don't bother accumulating proper equipment, or food. They're forever running out of fuel in the middle of nowhere. They don't take elementary precautions when meeting strangers. And after wading through the rotting corpses of the entire human race, they're as squeamish as sheltered debutantes. You have to constantly wonder how they could have survived this long... and even if they did, why anyone would want to make a movie about them.<br /><br />So when these dweebs stop to agonize over the moral dimensions of their actions, it's impossible to take their soul-searching seriously. Their actions would first have to make some kind of minimal sense.<br /><br />On top of all this, we must contend with the dubious acting abilities of Chris Pine. His portrayal of an arrogant young James T Kirk might have seemed shrewd, when viewed in isolation. But in Carriers he plays on exactly that same note: arrogant and boneheaded. It's impossible not to suspect that this constitutes his entire dramatic range.<br /><br />On the positive side, the film *looks* excellent. It's got an over-sharp, saturated look that really suits the southwestern US locale. But that can't save the truly feeble writing nor the paper-thin (and annoying) characters. Even if you're a fan of the end-of-the-world genre, you should save yourself the agony of watching Carriers."
    0 b'I saw this movie at an actual movie theater (probably the $2.00 one) with my cousin and uncle. We were around 11 and 12, I guess, and really into scary movies. I remember being so excited to see it because my cool uncle let us pick the movie (and we probably never got to do that again!) and sooo disappointed afterwards!! Just boring and not scary. The only redeeming thing I can remember was Corky Pigeon from Silver Spoons, and that wasn\'t all that great, just someone I recognized. I\'ve seen bad movies before and this one has always stuck out in my mind as the worst. This was from what I can recall, one of the most boring, non-scary, waste of our collective $6, and a waste of film. I have read some of the reviews that say it is worth a watch and I say, "Too each his own", but I wouldn\'t even bother. Not even so bad it\'s good.'
    """
    

    创建一个高性能的数据集(dataset)

    这是加载数据时应该使用的两种重要方法,以确保I/O不会阻塞

    • .cache():将数据从磁盘加载后保留在内存中。这将确保数据集在训练模型时不会成为瓶颈。如果数据集太大,无法放入内存,也可以使用此方法创建一个性能良好的磁盘缓存,它比许多小文件读取效率更高。
    • .prefetch():使数据预处理与模型的训练交替进行
    AUTOTUNE = tf.data.AUTOTUNE
    
    train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
    val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
    

    使用嵌入层(Embedding层)

    Embedding层可以理解成一个从整数索引(代表特定词汇)映射到密集向量(该单词对应的embeddings)的一个查找表。你可以通过试验确定最佳嵌入维度,就和你确定Dense层的最佳神经元个数那样做。

    # 输入1000个单词,每个单词用5个维度的向量表示
    embedding_layer = tf.keras.layers.Embedding(1000, 5)
    

    当你创建Embedding层时,Embedding层的权重(weights)将会和其他层(layer)一样被随机初始化。在训练过程中,权重会逐渐通过反向传播来进行调整。训练过后,embeddings层将会粗略的编码词汇之间的相似性(这个是针对你所训练模型的特定问题的)。

    如果将整数传递给嵌入层,则结果将用嵌入表中的向量替换每个整数。

    result = embedding_layer(tf.constant([1,2,3]))
    result.numpy()
    """
    输出:
    array([[-0.01827962,  0.033703  ,  0.02065292,  0.00335936, -0.00998179],
           [ 0.00618695, -0.02138543, -0.01288087,  0.03814398, -0.02176479],
           [-0.02900024,  0.03794893, -0.03229412,  0.04951945,  0.03212232]],
          dtype=float32)
    """
    

    对于文本或序列问题,嵌入向量层采用整数组成的 2D 张量,其形状为 (samples, sequence_length),其中每个条目都是一个整数序列。它可以嵌入可变长度的序列。您可以在形状为 (32, 10)(32 个长度为 10 的序列组成的批次)或 (64, 15)(64 个长度为 15 的序列组成的批次)的批次上方嵌入向量层。

    返回的张量比输入多一个轴,嵌入向量沿新的最后一个轴对齐。向其传递 (2, 3) 输入批次,输出为 (2, 3, N)

    result = embedding_layer(tf.constant([[0,1,2],[3,4,5]]))
    result.shape
    """
    输出:TensorShape([2, 3, 5])
    """
    

    当给定一个序列批次作为输入时,嵌入向量层将返回形状为 (samples, sequence_length, embedding_dimensionality) 的 3D 浮点张量。


    代码:可在微信公众号【明天依旧可好】中回复:05

    注: 本文参考了官网并对其进行了删减以及部分注释与修改

    展开全文
  • JavaSE基础-String类

    2020-07-28 22:47:48
    String类概述 String 字符串:就是有一个或多个字符组成的序列。 字符串可以看成是字符数组,一个...//创建一个字符类对象 int length1 = s.length(); System.out.println(length1); int length = "abc".length();

    String类概述
    String 字符串:就是有一个或多个字符组成的序列。
    字符串可以看成是字符数组,每一个字符从左往后编有索引,从0开始
    String 类有以下两句话

    1. Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
    理解:
    String s = new String("abc");//创建一个字符类对象
    int length1 = s.length();
    System.out.println(length1);
    
    int length = "abc".length();
    System.out.println(length);
    上述两种方式等价,第一种需要创建一个String类对象并传入字符串,第二种直接使用字面值进行调用
    length()方法,两种方法结果一样,因此所有字符串字面值(如 "abc" )都作为此类的实例实现。
    1. 字符串是常量,它们的值在创建之后不能更改,详解如下图,字符串一旦定义就不能更改,因为字符串的值是指字符常量池内创建的值,而在Srting类中定义的变量字符串,他指向的是字符串常量池中的值,因此,如果你想改变值的话,改变的是该字符串的指向(或者说是引用,没办法改变常量池内的值)
      在这里插入图片描述
      String类中地址问题代码举例
    public class MyTest6 {
        public static void main(String[] args) {
            String s1 = new String("abc");
            String s2="abc";
            String s3 = "abc";
            System.out.println(s1==s2); //false
            System.out.println(s2==s3); //true
        }
    }
    
    

    在这里插入图片描述

    String常见的方法:

    public String()    无参构造方法
    public String(byte[] bytes)   把字节数组转换成一个字符串
    public String(byte[] bytes,int index,int length)  把字节数组从index下标开始到length个元素转换成字符串
    public String(char[] value)   把一个字符数组转换成一个字符串
    public String(char[] value,int index,int count)  把一个字符数组从index下标处开始的count个字符转换成字符串
    public String(String original) 把一个字符串转换成一个字符串
    public boolean equals(Object obj)  比较字符串是否相等,比较的是内容,区分大小写
    public boolean equalsIgnoreCase(String str)  比较字符串是否相等,比较的是内容,不去分大小写
    public boolean contains(String str) 判断一个字符串是否包含Str字符串
    public boolean startsWith(String str) 判断一个字符串是否一Str这个字符串开始
    public boolean endsWith(String str) 判断一个字符串是否以Str这个字符串结尾
    public boolean isEmpty() 判断该字符是不是一个空字符
    public int length() 取字符串的长度
    public char charAt(int index) 返回指定索引的charpublic int indexOf(int ch)  返回在指定字符的第一个发生的字符串中的索引。
    public int indexOf(String str) 返回指数在这个字符串指定的子字符串中第一个出现的。
    public int indexOf(int ch,int fromIndex) 返回在指定字符的第一个发生的字符串中的索引,在指定的索引处开始搜索。 
    public int indexOf(String str,int fromIndex) 返回此字符串的指定子字符串中第一个出现在索引中,从指定索引处开始。
    public String substring(int start) 返回一个字符串,这个字符串的子串。
    public String substring(int start,int end) 返回一个字符串,这个字符串的子串。
    public byte[] getBytes()这 String 编码成一个序列使用平台的默认字符集字节,结果存放到一个新的字节数组。
    public char[] toCharArray() 将此字符串转换为一个新的字符数组。
    public static String valueOf(char[] chs) 返回的 char数组参数的字符串表示形式。
    public static String valueOf(int i) 返回的 int参数的字符串表示形式。
    public String toLowerCase()  将字符改变成小写
    public String toUpperCase()  将字符改写成大写 
    public String concat(String str) 拼接字符串
    public String replace(char old,char new) 将字符串中的old(想要被替换的旧字符)替换成new(想要的新的字符)
    public String replace(String old,String new) 将字符串中的old(想要被替换的旧字符串)替换成new(想要的新的字符串)
    public String trim() 返回一个字符串,它的值是字符串,任何前导和尾随空格删除
    public int compareTo(String str) 比较两个字符串的字典。
    public int compareToIgnoreCase(String str)  按字典顺序比较两个字符串,忽略大小写的差异。

    String方法应用举例

    1.equals方法举例(equals()方法被重写了,因此该方法比较的是字符串字面值是否相等,不再是对地址进行对比)
    校验用户名密码与已创建的用户信息是否一致
    public class MyTest {
        public static void main(String[] args) {
            String name="zhangsan";
            String password="123456";     
                while(true) {
                    System.out.println("请输入用户名");
                    Scanner sc = new Scanner(System.in);
                    String s = sc.nextLine();
                    if (s.equals(name)) {
                    //s.equals(name)比较值是否相等
                        for (int i = 1; i <= 3;i++) {
                           System.out.println("请输入密码:");
                            Scanner sc1 = new Scanner(System.in);
                            String s1 =sc1.nextLine();
                            if (s1.equals(password)){
                            //s1.equals(password)比较值是否相等
                               System.out.println("登录成功");
                                break;
                            } else {
                              System.out.println("密码输入错误,请重新输入" + "您还有" + (3 - i) + "次机会");
                            }
                        }
    
                        break;
    
                    } else {
    
                        System.out.println("用户名输入错误");
    
                    }
    
                }
    
        }
    
    }
    2.indexOf()substring()的应用举例
    public class MyTest {
        public static void main(String[] args) {
            System.out.println("abc".length());
            String str="abc";
            //根据索引,获取字符串中的单个字符
             //StringIndexOutOfBoundsException:
            char c = str.charAt(1);
            System.out.println(c);
            //返回指定字符在此字符串中第一次出现处的索引。
            String str2="cdoqvbhecoqvhiqo";
            int index = str2.indexOf('c');
            System.out.println(index);
            //如果返回 -1 表示没有找到
            int index2 = str2.indexOf("bh2222");
            System.out.println(index2);
            System.out.println("==============================");
            //从你指定的索引出开始查找改字符第一次出现的索引
            int index1 = str2.indexOf("c", 1);
            System.out.println(index1);
            int index3 = str2.indexOf("c", str2.indexOf("c") + 1);
            System.out.println(index3);
            System.out.println("=====================================");
            //从后往前进行检索
            int index4 = str2.lastIndexOf("h");
            System.out.println(index4);
            System.out.println("=========================");
            String str3 = "好好学习,天天向上";
            //从指定的索引出,截取到末尾返回
            String substring = str3.substring(4);
            System.out.println(substring);
            //根据起始索引和终止索引截取一部分字符串,,是含头不含尾
            String substring2 = str3.substring(0,4);
            System.out.println(substring2);
        }
    }
    3.chartAt()的应用
    举例:统计字符串大小写以及数字有多少个
    public class demo2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入字符串");
            String s=sc.nextLine();
            int daxie=0;
            int xiaoxie=0;
            int shuzi=0;
            int qita=0;
            for (int i = 0; i < s.length(); i++) {
                char ss=s.charAt(i);
                //public char charAt(int index) 返回指定索引的char值
                if(ss>='A'&&ss<='Z'){
                    daxie++;
                }else if(ss>='a'&&ss<='z'){
                    xiaoxie++;
                }else if(ss>='0'&&ss<='9'){
                    shuzi++;
                }
                else{
                    qita++;
                }
            }
            System.out.println("大写:"+daxie);
            System.out.println("小写:"+xiaoxie);
            System.out.println("数字:"+shuzi);
            System.out.println("其他:"+qita);
        }
    }
    
    4.toUpperCase()toLowerCase()
    String s2 = "abc".toUpperCase();//将小写转换为大写
    String s3 = "BcD".toLowerCase();//将大写转换为小写
    5.replace()trim()的应用
    String str = "aaa=bbb=ccc";// "aaabbbccc"
    String re= str.replace("=", "");
    System.out.println(re);
    
    String s = "     张    三   ";
    
    String replace2 = s.replace(" ", "");
    System.out.println("-----"+replace2+"-------------");//张三,将所有的空格替换调
    //去除字符串的两端空格
    String trim = s.trim();
    System.out.println(trim);//trim()方法是将字符串两端的空格去掉
    
    具体应用实力举例:
    public class demo7 {
    public static void main(String[] args) {
    	String s = "     z  h   a   n  g  s  an    ";
    	int index=s.indexOf('z');
            String s1=s.substring(0,index).replace(" ","").concat(s.substring(index));       
    	System.out.println("-"+s1+"-");//去左端
    
           System.out.println("=========================");
            int index1=s.lastIndexOf("n");
            String s2=s.substring(0,index1+1);
            System.out.println("-"+s2+"-");//去右端       
    	System.out.println("===========================");
            String s3=s.replace(" ","");
            String s4=s.substring(0,index).concat(s3).concat(s.substring(index1+1));//去中间       
    	//public String concat(String str) 拼接字符串
    	System.out.println("-"+s4+"-");//去中间
        }
    
    }

    注意:
    1.String 类中重写了Object类中的toString方法,因此String类的对象在调用toString方法时,会打印字符串字面值,而不是对象的地址值。
    2.equals方法也被重写,比较是值,不再是地址值。

    展开全文
  • 黑马面试题 1定义map集合并自定义对象对map集合遍历打出key和...4把盘中的一个多层文件夹拷贝到D盘中用高效的方法要求写思路注释代码 5Integer泛型Map中存储字符串 6开启两个线程隔一段时间分别向一个共享数组中添
  • 每个属性都应定义以下限制:常量列表,数字范围,字符串长度或字符串格式,对象模式或数组模式或其他。 例如,您可以使用joi语言定义限制: : API定义 定义WEB系统将要使用的特定服务(konkrečiospaslaugos)API...
  • 用数字表示文本 机器学习模型将向量(数字数组)作为输入。在处理文本时,我们必须先想出一种...为了表示个单词,我们将创建一个长度等于词汇量的零向量,然后在与该单词对应的索引中放置一个 1。 为了创建一个包含

    用数字表示文本

    机器学习模型将向量(数字数组)作为输入。在处理文本时,我们必须先想出一种策略,将字符串转换为数字(或将文本“向量化”),然后再其馈入模型。

    实现这一目标的三种策略:

    独热编码

    作为第一个想法,可以对词汇表中的每个单词进行“独热”编码。考虑这样一句话:“The cat sat on the mat”。这句话中的词汇(或唯一单词)是(cat、mat、on、sat、the)。为了表示每个单词,我们将创建一个长度等于词汇量的零向量,然后在与该单词对应的索引中放置一个 1。

    为了创建一个包含句子编码的向量,我们可以将每个单词的独热向量连接起来。

    要点:这种方法效率低下。一个独热编码向量十分稀疏(这意味着大多数索引为零)。假设我们的词汇表中有 10,000 个单词。为了对每个单词进行独热编码,我们将创建一个其中 99.99% 的元素都为零的向量。

    用一个唯一的数字编码每个单词

    第二种方法是使用唯一的数字来编码每个单词。继续上面的示例,可以将 1 分配给“cat”,将 2 分配给“mat”,依此类推。然后,我们可以将句子“The cat sat on the mat”编码为一个密集向量,例如 [5, 1, 4, 3, 5, 2]。这种方法是高效的。现在,我们有了一个密集向量(所有元素均已满),而不是稀疏向量。

    但是,这种方法有两个缺点:

    • 整数编码是任意的(它不会捕获单词之间的任何关系)。

    • 对于要解释的模型而言,整数编码颇具挑战。例如,线性分类器针对每个特征学习一个权重。由于任何两个单词的相似性与其编码的相似性之间都没有关系,因此这种特征权重组合没有意义。

    单词嵌入向量

    单词嵌入向量为我们提供了一种使用高效、密集表示的方法,其中相似的单词具有相似的编码。重要的是不必手动指定此编码。嵌入向量是浮点值的密集向量(向量的长度是可以指定的参数)。它们是可以训练的参数(模型在训练过程中学习的权重,与模型学习密集层权重的方法相同),无需手动为嵌入向量指定值。8 维的单词嵌入向量(对于小型数据集)比较常见,而在处理大型数据集时最多可达 1024 维。维度更高的嵌入向量可以捕获单词之间的细粒度关系,但需要更多的数据来学习。Word Embedding矩阵给每个单词分配一个固定长度的向量表示,这个长度可以自行设定,比如300,实际上会远远小于字典长度(比如10000)。而且两个单词向量之间的夹角值可以作为他们之间关系的一个衡量。如下表示:

    Word Embedding表示法

    通过简单的余弦函数,我们就可以计算两个单词之间的相关性,简单高效:

    import tensorflow as tf
    from icecream import ic
    from tensorflow import keras
    from tensorflow.keras import layers
    #1 导入数据
    import tensorflow_datasets as tfds
    tfds.disable_progress_bar()
    #2 使用嵌入向量层
    '''
    可以将嵌入向量层理解为一个从整数索引(代表特定单词)映射到密集向量(其嵌入向量)的查找表。嵌入向量的维数(或宽度)是一个参数,
    可以试验它的数值,以了解多少维度适合问题,这与试验密集层中神经元数量的方式非常相似。
    '''
    embedding_layer = layers.Embedding(1000, 5)
    '''
    创建嵌入向量层时,嵌入向量的权重会随机初始化(就像其他任何层一样)。在训练过程中,通过反向传播来逐渐调整这些权重。
    训练后,学习到的单词嵌入向量将粗略地编码单词之间的相似性(因为它们是针对训练模型的特定问题而学习的)。
    '''
    #如果将整数传递给嵌入向量层,结果会将每个整数替换为嵌入向量表中的向量:
    result = embedding_layer(tf.constant([1,2,3]))
    ic(result.numpy())

    运行结果:

    ic| result.numpy(): array([[-0.04286907,  0.01746731,  0.03539313, -0.04714948,  0.01741666],
                               [-0.0271346 , -0.04651893,  0.03715916,  0.02202106, -0.04117215],
                               [-0.00178969,  0.01628102,  0.03589281,  0.01006144,  0.03929297]],
                              dtype=float32)
    
    '''
    对于文本或序列问题,嵌入向量层采用整数组成的 2D 张量,其形状为 (samples, sequence_length),
    其中每个条目都是一个整数序列。它可以嵌入可变长度的序列。您可以在形状为 (32, 10)(32 个长度为 10 的序列组成的批次)或 
    (64, 15)(64 个长度为 15 的序列组成的批次)的批次上方馈入嵌入向量层。
    '''
    #返回的张量比输入多一个轴,嵌入向量沿新的最后一个轴对齐。向其传递 (2, 3) 输入批次,输出为 (2, 3, N)
    #result = embedding_layer(tf.constant([[0,1,2],[3,4,5]]))
    #ic(result.shape)
    #ic| result.shape: TensorShape([2, 3, 5]),这里的5,是之前embeddiing(1000,5)层设置的5维参数
    '''
    当给定一个序列批次作为输入时,嵌入向量层将返回形状为 (samples, sequence_length, embedding_dimensionality) 的 3D 浮点张量。
    为了从可变长度的序列转换为固定表示,有多种标准方法。可以先使用 RNN、注意力或池化层,然后再将其传递给密集层。下面使用池化,因为它最简单。
    以后使用 RNN 进行文本分类是一个不错的选择。
    '''

    从头开始学习嵌入向量

    #基于 IMDB 电影评论来训练情感分类器
    import tensorflow as tf
    from icecream import ic
    from tensorflow import keras
    from tensorflow.keras import layers
    
    #1 导入数据
    import tensorflow_datasets as tfds
    tfds.disable_progress_bar()#Disabled Tqdm progress bar.
    (train_data, test_data), info = tfds.load(
        'imdb_reviews/subwords8k',
        split = (tfds.Split.TRAIN, tfds.Split.TEST),
        with_info=True, as_supervised=True)
    
    
    #2 获取编码器 (tfds.features.text.SubwordTextEncoder),并快速浏览词汇表。
    #词汇表中的“”代表空格。请注意词汇表如何包含完整单词(以“”结尾)以及可用于构建更大单词的部分单词:
    encoder = info.features['text'].encoder
    ic(encoder.subwords[:20])
    
    
    #3 电影评论的长度可以不同。我们将使用 padded_batch 方法来标准化评论的长度。
    train_batches = train_data.shuffle(1000).padded_batch(10)
    #3.1 打乱数据 shuffle(1000)
    # 从train_data数据集中按顺序抽取buffer_size(1000)个样本放在buffer中,然后打乱buffer中的样本
    # buffer中样本个数不足buffer_size,继续从data数据集中安顺序填充至buffer_size,
    # 此时会再次打乱
    test_batches = test_data.shuffle(1000).padded_batch(10)
    '''
    dataset.shuffle作用是将数据进行打乱操作,传入参数为buffer_size,改参数为设置“打乱缓存区大小”,
    也就是说程序会维持一个buffer_size大小的缓存,每次都会随机在这个缓存区抽取一定数量的数据
    dataset.batch作用是将数据打包成batch_size
    dataset.repeat作用就是将数据重复使用多少epoch
    '''
    '''
    padded_batch(
        batch_size, padded_shapes=None, padding_values=None, drop_remainder=False
    )
    注意参数drop_remainder用来约束最后一个batch是不是要丢掉,当这个batch样本数少于batch_size时,
    比如batch_size = 3,最后一个batch只有2个样本。默认是不丢掉
    padded_batch是非常见的一个操作,比如对一个变长序列,通过padding操作将每个序列补成一样的长度。
    特点:
    1)padded_shapes使用默认值或者设置为-1,那么每个batch padding后每个维度就是跟这个者个batch的样本各个维度最大值保持一致
    2)当shape固定为特定的size时,那么每个batch的shape就是一样的。
    '''
    #导入时,评论的文本是整数编码的(每个整数代表词汇表中的特定单词或单词部分)。
    #请注意尾随零,因为批次会填充为最长的示例。
    #train_batch, train_labels = next(iter(train_batches))
    #train_batch.numpy()
    '''
    array([[5739,   46,  674, ...,    0,    0,    0],
           [ 274, 2732, 1289, ...,    0,    0,    0],
           [  19,  118,  874, ...,    0,    0,    0],
           ...,
           [ 324,   12,  118, ...,    0,    0,    0],
           [  12,   31,  165, ...,    0,    0,    0],
           [ 131,  196, 7968, ...,    0,    0,    0]])
    '''
    
    
    #4 创建一个简单模型
    '''
    使用 Keras 序列式 API 定义模型。在这种情况下,它是一个“连续词袋”样式的模型。
    小心:此模型不使用遮盖,而是使用零填充作为输入的一部分,因此填充长度可能会影响输出。
    '''
    embedding_dim=16
    model = keras.Sequential([
      #嵌入向量层将采用整数编码的词汇表,并查找每个单词索引的嵌入向量。在模型训练时会学习这些向量。
      #向量会向输出数组添加维度。得到的维度为:(batch, sequence, embedding)。
      layers.Embedding(encoder.vocab_size, embedding_dim),
      #接下来,通过对序列维度求平均值,GlobalAveragePooling1D 层会返回每个样本的固定长度输出向量。
      #这让模型能够以最简单的方式处理可变长度的输入。
      layers.GlobalAveragePooling1D(),
      #此固定长度输出向量通过一个包含 16 个隐藏单元的完全连接(密集)层进行流水线传输。
      layers.Dense(16, activation='relu'),
      #最后一层与单个输出节点密集连接。利用 Sigmoid 激活函数,得出此值是 0 到 1 之间的浮点数,表示评论为正面的概率(或置信度)。
      layers.Dense(1)
    ])
    
    #model.summary()
    '''
    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    embedding_1 (Embedding)      (None, None, 16)          130960    
    _________________________________________________________________
    global_average_pooling1d (Gl (None, 16)                0         
    _________________________________________________________________
    dense (Dense)                (None, 16)                272       
    _________________________________________________________________
    dense_1 (Dense)              (None, 1)                 17        
    =================================================================
    Total params: 131,249
    Trainable params: 131,249
    Non-trainable params: 0
    _________________________________________________________________
    '''
    
    
    #5 编译和训练模型
    model.compile(optimizer='adam',
                  loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                  metrics=['accuracy'])
    
    history = model.fit(
        train_batches,
        epochs=10,
        validation_data=test_batches, validation_steps=20)
    
    
    #6 绘制训练准确率和验证准确率图
    import matplotlib.pyplot as plt
    
    history_dict = history.history
    
    acc = history_dict['accuracy']
    val_acc = history_dict['val_accuracy']
    loss=history_dict['loss']
    val_loss=history_dict['val_loss']
    
    epochs = range(1, len(acc) + 1)
    
    plt.figure(figsize=(12,9))
    plt.plot(epochs, loss, 'bo', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Validation loss')
    plt.title('Training and validation loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()
    
    plt.figure(figsize=(12,9))
    plt.plot(epochs, acc, 'bo', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Validation acc')
    plt.title('Training and validation accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend(loc='lower right')
    plt.ylim((0.5,1))
    plt.show()
    
    #7 检索学习的嵌入向量
    #检索在训练期间学习的单词嵌入向量。这将是一个形状为 (vocab_size, embedding-dimension) 的矩阵。
    e = model.layers[0]
    weights = e.get_weights()[0]
    #print(weights.shape) # shape: (vocab_size, embedding_dim)
    #(8185, 16)
    #将权重写入磁盘。要使用 Embedding Projector,我们将以制表符分隔的格式上传两个文件:一个向量文件(包含嵌入向量)和一个元数据文件(包含单词)。
    import io
    encoder = info.features['text'].encoder
    out_v = io.open('vecs.tsv', 'w', encoding='utf-8')
    out_m = io.open('meta.tsv', 'w', encoding='utf-8')
    for num, word in enumerate(encoder.subwords):
      vec = weights[num+1] # skip 0, it's padding.
      out_m.write(word + "\n")
      out_v.write('\t'.join([str(x) for x in vec]) + "\n")
    out_v.close()
    out_m.close()
    
    
    #8 可视化嵌入向量
    '''
    为了可视化嵌入向量,我们将它们上传到 Embedding Projector。
    打开 Embedding Projector:http://projector.tensorflow.org/(也可以在本地 TensorBoard 实例中运行)。
        点击“Load data”。
        上传我们在上面创建的两个文件:vecs.tsv 和 meta.tsv。
    将显示已训练的嵌入向量。可以搜索单词以查找其最邻近。例如,尝试搜索“beautiful”,可能会看到“wonderful”等相邻单词。
    注:结果可能会略有不同,具体取决于训练嵌入向量层之前如何随机初始化权重。
    注:可以试验性地使用更简单的模型来生成更多可解释的嵌入向量。尝试删除 Dense(16) 层,重新训练模型,然后再次可视化嵌入向量。
    '''
    

     

    展开全文
  • // 比如v-for指令会为数组的一个元素创建一个scope,这个scope就继承自vm或上级数组元素的scope, // 这样就可以在v-for的作用域中访问父级的数据 this._proxy(key) } // observe data //重点来了 observe...
  • javascript入门笔记

    2018-05-15 15:01:07
    1、先创建一个 base.js 的文件 2、在文件中执行以下代码 console.log(" .... ... "); [removed](" ... ... "); window.alert("这是在外部脚本文件中的内容"); 3、在 html 文档中,引入 base.js 文件 ...
  • 正则表达式

    2014-12-03 14:51:39
    捷方式了,它还实施了一条规约,那就是一个字符串各个分离的部分包含的是完全相同的字符.例如:下面的正则表达式匹配的就是位于单引号或双引号之内的所有字 符.但是,它要求开始和结束的引号匹配(例如两个都是双引号...
  • 1371.个元音包含偶数次的最长子字符串 1381. 设计一个支持增量操作的栈 91 1423. 可获得的最大点数 1438. 绝对差不超过限制的最长连续子数组 1558. 得到目标数组的最少函数调用次数 1574. 删除最短的子数组使...
  • JAVA面试题最全集

    2010-03-13 13:09:10
    一个方法,实现字符串的反转,如:输入abc,输出cba 写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc。 3.数据类型之间的转换 如何将数值型字符转换为数字(Integer,Double) 如何将数字...
  • 而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们...
  • 最新Java面试宝典pdf版

    热门讨论 2011-08-31 11:29:22
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • Microsoft C# Windows程序设计(上下册)

    热门讨论 2011-08-05 10:28:13
    4.5 样东西都是一个对象 4.6 列出系统信息 4.7 windows窗体和滚动条 4.8 滚动面板控件 4.9 scrollablecontrol的继承关系 4.10 没有控件的滚动 4.11 实际数值 4.12 保持最新 4.13 不要成为一头猪 ...
  • Java面试宝典-经典

    2015-03-28 21:44:36
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  •  SessionBean: Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立一个Bean的实例时,EJB容器不一定要创建一个新的Bean的实例供客户机调用,而是随便找一个现有的实例提供给客户机。...
  • Java面试宝典2010版

    2011-06-27 09:48:27
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • c#学习笔记.txt

    2008-12-15 14:01:21
    1. 使用上述指导创建一个一般集合,另外实现 IEnumerable 接口。此集合可用于其他语言(如 Visual Basic)。 2. 在集合类中使用一个预定义的集合。 (2) throw 语句用于发出在程序执行期间出现反常情况(异常)的...
  • Java面试宝典2012版

    2012-12-03 21:57:42
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • 3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • java面试宝典2012

    2012-12-16 20:43:41
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • Java面试笔试资料大全

    热门讨论 2011-07-22 14:33:56
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • Java面试宝典2012新版

    2012-06-26 19:20:00
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...
  • JAVA面试宝典2010

    2011-12-20 16:13:24
    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

空空如也

空空如也

1 2 3 4
收藏数 68
精华内容 27
关键字:

创建一个字符串数组每句话