การจดจำเสียง:“ ใช่” หรือ“ ไม่”?


33

งาน

ใช้โปรแกรมอย่างน้อยไบต์ของซอร์สโค้ดหรือรหัสไบนารี่ที่ทำการรู้จำเสียงของตัวอย่างเสียง (ฉันพูดว่า "ใช่", "ใช่" หรือ "ไม่" ในเสียงหรือกระซิบชัดแจ้งหรือเล่นโวหาร) ตามตัวอย่างการฝึกอบรมที่มีความแม่นยำสูงสุด .

โปรแกรมที่ควรอ่านtrain/yes0.wav, train/no0.wav, train/yes1.wavและอื่น ๆ (มี 400 yeses และ 400 noes ในชุดฝึกอบรม) แล้วเริ่มต้นการอ่านinputs/0.wav, inputs/1.wavจนกว่าจะล้มเหลวในการค้นหาไฟล์, การวิเคราะห์และแสดงผลว่า "ใช่" หรือ "ไม่ใช่" (หรือคำอื่น ๆ สำหรับ คำตอบระดับกลาง)

หากคุณต้องการคุณสามารถฝึกฝนโปรแกรมล่วงหน้าแทนการอ่านtrain/แต่ตารางข้อมูลผลลัพธ์จะนับรวมคะแนน (และระวังการ overfitting ตัวอย่างการฝึกอบรม - พวกเขาไม่ทับซ้อนกับการตรวจสอบ) ดีกว่าที่จะรวมโปรแกรมที่ใช้สร้างตารางข้อมูลเป็นภาคผนวกในกรณีนี้

ไฟล์ตัวอย่างทั้งหมดเป็นไฟล์ WAV สเตอริโอ 16 บิตแบบ endian เพียงเล็กน้อยจากแล็ปท็อปไมค์โดยไม่ต้องกรอง / ลดเสียงรบกวน

ขีด จำกัด

คุณสมบัติต้องห้าม:

  • ใช้เครือข่าย
  • พยายามที่จะเข้าถึงแฟ้มคำตอบinputs/key;
  • การทำลายrunnerโปรแกรมที่คำนวณความแม่นยำ
  • การใช้ไลบรารีการจดจำที่มีอยู่ ไม่อนุญาตให้เชื่อมโยงไปยังการใช้ FFT: อนุญาตให้ใช้ฟังก์ชันคณิตศาสตร์ภายนอกที่รับข้อมูลจำนวนคงที่ (เช่นsinหรือatan2) เท่านั้น หากคุณต้องการ FFT เพียงเพิ่มการติดตั้งไปยังซอร์สโค้ดโปรแกรมของคุณ (สามารถพูดได้หลายภาษาหากจำเป็น)

ข้อ จำกัด ทรัพยากร:

  • โปรแกรมไม่ควรใช้เวลา CPU มากกว่า 30 นาทีบนแล็ปท็อป i5 ของฉัน หากใช้เวลามากกว่าจะนับเฉพาะผลผลิตที่ผลิตใน 30 นาทีแรกเท่านั้นและจะมีการนับอีกครึ่งหนึ่ง
  • จำกัด หน่วยความจำ: 1GB (รวมถึงไฟล์ชั่วคราว);

เครื่องมือ

tools/runnerโปรแกรมจะทำงานโดยอัตโนมัติวิธีการแก้ปัญหาของคุณและคำนวณความถูกต้อง

$ tools/runner solutions/example train train/key 
Accuracy: 548 ‰

สามารถตรวจสอบโปรแกรมโดยใช้ข้อมูลการฝึกอบรมหรือใช้ข้อมูลการสอบจริง ฉันจะลองส่งคำตอบเกี่ยวกับชุดข้อมูลการตรวจสอบและเผยแพร่ผลลัพธ์ (เปอร์เซ็นต์ความแม่นยำ) จนกว่าฉันจะเผยแพร่ชุดข้อมูลให้เป็นสาธารณะ

เกณฑ์การให้คะแนน

โซลูชันมี 5 ระดับขึ้นอยู่กับความถูกต้อง:

  • ตัวอย่างทั้งหมดเดาอย่างถูกต้อง: คลาส 0;
  • ความแม่นยำ 950-999: รุ่นที่ 1;
  • ความแม่นยำ 835-950: Class 2;
  • ความแม่นยำ 720-834: รุ่นที่ 3;
  • ความแม่นยำ 615-719: Class 4;

ภายในแต่ละชั้นเรียนคะแนนคือจำนวนไบต์ที่ใช้ในการแก้ปัญหา

คำตอบที่ได้รับการยอมรับ: ทางออกที่เล็กที่สุดในชั้นเรียนที่ไม่ว่างเปล่าที่ดีที่สุด

การเชื่อมโยง

  • โครงการ Github ด้วยเครื่องมือ: https://github.com/vi/codegolf-jein
  • ชุดข้อมูลการฝึกอบรม: http://vi-server.org/pub/codegolf-jein-train.tar.xz
  • ชุดข้อมูลการตรวจสอบจะถูกเก็บเป็นส่วนตัวจนถึงขณะนี้ยังมี checksums (HMAC) ในที่เก็บ Github

ตัวอย่างทั้งหมดควรพิจารณา CC-0 (โดเมนสาธารณะ) สคริปต์และโปรแกรมควรพิจารณา MIT

ตัวอย่างการแก้ปัญหา

มันให้คุณภาพการรับรู้ที่ต่ำมากเพียงแค่แสดงวิธีอ่านไฟล์และคำตอบเอาต์พุต

#define _BSD_SOURCE
#include <stdio.h>
#include <assert.h>
#include <endian.h>


#define Nvols 30

#define BASS_WINDOW 60
#define MID_WINDOW 4

struct training_info {
    double bass_volumes[Nvols];
    double mid_volumes[Nvols];
    double treble_volumes[Nvols];
    int n;
};


struct training_info yes;
struct training_info no;

static int __attribute__((const)) mod(int n, int d) {
    int m = n % d;
    if (m < 0) m+=d;
    return m;
}

// harccoded to 2 channel s16le
int get_file_info(const char* name, struct training_info *inf) {
    FILE* in = fopen(name, "rb");

    if (!in) return -1;

    setvbuf(in, NULL, _IOFBF, 65536);

    inf->n = 1;

    fseek(in, 0, SEEK_END);
    long filesize = ftell(in);
    fseek(in, 128, SEEK_SET);
    filesize -= 128; // exclude header and some initial samples

    int nsamples = filesize / 4; 

    double bass_a=0, mid_a=0;
    const int HISTSIZE  = 101;
    double xhistory[HISTSIZE];
    int histpointer=0;
    int histsize = 0;

    //FILE* out = fopen("debug.raw", "wb");

    int i;
    for (i=0; i<Nvols; ++i) {
        int j;

        double total_vol = 0;
        double bass_vol = 0;
        double mid_vol = 0;
        double treble_vol = 0;

        for (j=0; j<nsamples / Nvols; ++j) {
            signed short int l, r; // a sample
            if(fread(&l, 2, 1, in)!=1) break;
            if(fread(&r, 2, 1, in)!=1) break;
            double x = 1/65536.0 * ( le16toh(l) + le16toh(r) );


            bass_a += x;
            mid_a  += x;


            if (histsize == HISTSIZE-1) bass_a   -= xhistory[mod(histpointer-BASS_WINDOW,HISTSIZE)];
            if (histsize == HISTSIZE-1) mid_a    -= xhistory[mod(histpointer-MID_WINDOW ,HISTSIZE)];

            double bass = bass_a / BASS_WINDOW;
            double mid = mid_a / MID_WINDOW - bass;
            double treble = x - mid_a/MID_WINDOW;

            xhistory[histpointer++] = x;
            if(histpointer>=HISTSIZE) histpointer=0;
            if(histsize < HISTSIZE-1) ++histsize;

            total_vol  += bass*bass + mid*mid + treble*treble;
            bass_vol   += bass*bass;
            mid_vol    += mid*mid;
            treble_vol += treble*treble;


            /*
            signed short int y;
            y = 65536 * bass;

            y = htole16(y);
            fwrite(&y, 2, 1, out);
            fwrite(&y, 2, 1, out);
            */
        }

        inf->bass_volumes[i] = bass_vol / total_vol;
        inf->mid_volumes[i] = mid_vol / total_vol;
        inf->treble_volumes[i] = treble_vol / total_vol;

        //fprintf(stderr, "%lf %lf %lf    %s\n", inf->bass_volumes[i], inf->mid_volumes[i], inf->treble_volumes[i], name);
    }
    fclose(in);

    return 0;
}

static void zerotrdata(struct training_info *inf) {
    int i;
    inf->n = 0;
    for (i=0; i<Nvols; ++i) {
        inf->bass_volumes[i] = 0;
        inf->mid_volumes[i] = 0;
        inf->treble_volumes[i] = 0;
    }
}

static void train1(const char* prefix, struct training_info *inf) 
{
    char buf[50];

    int i;

    for(i=0;; ++i) {
        sprintf(buf, "%s%d.wav", prefix, i);
        struct training_info ti;
        if(get_file_info(buf, &ti)) break;

        ++inf->n;

        int j;
        for (j=0; j<Nvols; ++j) {
            inf->bass_volumes[j]   += ti.bass_volumes[j];
            inf->mid_volumes[j]    += ti.mid_volumes[j];
            inf->treble_volumes[j] += ti.treble_volumes[j];
        }
    }

    int j;
    for (j=0; j<Nvols; ++j) {
        inf->bass_volumes[j]   /= inf->n;
        inf->mid_volumes[j]    /= inf->n;
        inf->treble_volumes[j] /= inf->n;
    }
}

static void print_part(struct training_info *inf, FILE* f) {
    fprintf(f, "%d\n", inf->n);
    int j;
    for (j=0; j<Nvols; ++j) {
        fprintf(f, "%lf %lf %lf\n", inf->bass_volumes[j], inf->mid_volumes[j], inf->treble_volumes[j]);
    }
}

static void train() {
    zerotrdata(&yes);
    zerotrdata(&no);

    fprintf(stderr, "Training...\n");

    train1("train/yes", &yes);
    train1("train/no", &no);

    fprintf(stderr, "Training completed.\n");

    //print_part(&yes, stderr);
    //print_part(&no, stderr);

    int j;
    for (j=0; j<Nvols; ++j) {
        if (yes.bass_volumes[j]   > no.bass_volumes[j]) {   yes.bass_volumes[j] = 1;   no.bass_volumes[j] = 0; }
        if (yes.mid_volumes[j]    > no.mid_volumes[j]) {    yes.mid_volumes[j] = 1;    no.mid_volumes[j] = 0; }
        if (yes.treble_volumes[j] > no.treble_volumes[j]) { yes.treble_volumes[j] = 1; no.treble_volumes[j] = 0; }
    }
}


double delta(struct training_info *t1, struct training_info *t2) {
    int j;
    double d = 0;
    for (j=0; j<Nvols; ++j) {
        double rb = t1->bass_volumes[j] - t2->bass_volumes[j];
        double rm = t1->mid_volumes[j] - t2->mid_volumes[j];
        double rt = t1->treble_volumes[j] - t2->treble_volumes[j];
        d += rb*rb + rm*rm + rt*rt;
    }
    return d;
}

int main(int argc, char* argv[])
{
    (void)argc; (void)argv;

    train();


    int i;

    int yes_count = 0;
    int no_count = 0;

    for (i=0;; ++i) {
        char buf[60];
        sprintf(buf, "inputs/%d.wav", i);

        struct training_info ti;

        if(get_file_info(buf, &ti)) break;

        double dyes = delta(&yes, &ti);
        double dno = delta(&no, &ti);

        //printf("%lf %lf %s ", dyes, dno, buf);

        if (dyes > dno) {
            printf("no\n");
            ++no_count;
        } else  {
            printf("yes\n");
            ++yes_count;
        }
    }

    fprintf(stderr, "yeses: %d noes: %d\n", yes_count, no_count);

}

5
ไม่มีไลบรารี fft หรือไม่ ทำไม?
John Dvorak

1
ฟังก์ชั่น FFT ในตัวคืออะไร สิ่งใดที่นับว่าเป็นสิ่งภายนอก นอกจากนี้สิ่งที่นับเป็นฟังก์ชั่นห้องสมุดคณิตศาสตร์? เราได้รับอนุญาตให้ใช้sumหรือเราจำเป็นต้องใช้foldl (+) 0(foldl ไม่ใช่คณิตศาสตร์เฉพาะและ+ไม่แปรปรวน)?
John Dvorak

1
ยังคง ... sumคุณได้อย่างมีประสิทธิภาพห้าม ฉันเดาว่านั่นไม่ใช่ความตั้งใจของคุณ?
John Dvorak

1
คำจำกัดความที่แน่นอนของฟังก์ชันคณิตศาสตร์คืออะไร? ผู้ที่มีความเชี่ยวชาญในการทำงานกับตัวเลข? สิ่งที่เกี่ยวกับฟังก์ชั่น "รวม" ทั่วไปที่ใช้การเพิ่มสำหรับตัวเลข แต่การต่อเชื่อมสตริง? ตอนนี้อนุญาตจำนวนนี้หรือไม่
John Dvorak

1
การดำเนินงานเวกเตอร์ของ J เป็นอย่างไร? พวกเขาไม่ได้รับอนุญาตหรือไม่
John Dvorak

คำตอบ:


27

C ++ 11 (gcc; 1639 1625 1635 bytes, Class 1, คะแนน = 983, 960)

มาเริ่มกันเลยดีกว่า มันอาจเป็นรหัสที่ยาวที่สุดที่ฉันเคยทำ ...

#include <bits/stdc++.h>
#define $ complex<double>
#define C vector<$>
#define I int
#define D double
#define P pair<D,I>
#define Q pair<D,D>
#define E vector<D>
#define V vector<P>
#define W vector<Q>
#define S char*
#define Z(x)if(fread(&x,2,1,y)!=1)break;
#define B push_back
#define F(i,f,t)for(I i=f;i<t;i++)
#define _ return
#define J first
#define L second
const I K=75,O=16384;using namespace std;C R(C&i,I s,I o=0,I d=1){if(!s)_ C(1,i[o]);C l=R(i,s/2,o,d*2),h=R(i,s/2,o+d,d*2);C r(s*2);$ b=exp($(0,-M_PI/s)),f=1;F(k,0,s){r[k]=l[k]+f*h[k];r[k+s]=l[k]-f*h[k];f*=b;}_ r;}C T(C&i){_ R(i,i.size()/2);}char b[O];E U(S m){FILE*y;if(!(y=fopen(m,"r")))_ E();setvbuf(y,b,0,O);fseek(y,0,2);I z=ftell(y)/4-32;fseek(y,128,0);C p;F(i,0,z){short l,r;Z(l);Z(r);if(i&1)p.B($(0.5/O*le16toh(l),0));}p.resize(O);E h(O),n(O);p=T(p);F(j,0,O)h[j]=norm(p[j])/O;F(i,1,O-1)n[i]=(h[i-1]+h[i+1]+h[i]*8)/10;fclose(y);_ n;}W G(E&d){V p;F(i,3,O/2-3)if(d[i]==*max_element(d.begin()+i-3,d.begin()+i+4))p.B({d[i],i});sort(p.begin(),p.end(),greater<P>());W r;F(i,3,K+3)r.B({D(p[i].L)/O*22050,log(p[i].J)+10});D s=0;F(i,0,K)s+=r[i].L;F(i,0,K)r[i].L/=s;_ r;}char m[O];I X(S p,W&r){E t(O),h(t);I f=0;while(1){sprintf(m,"%s%d.wav",p,f++);h=U(m);if(!h.size())break;F(j,0,O)t[j]+=h[j];}F(j,0,O)t[j]/=f;r=G(t);}D Y(W&a,W&b){D r=0;F(i,0,K){D d=b[i].L;F(j,0,K)if(abs((b[i].J-a[j].J)/b[i].J)<0.015)d=min(d,abs(b[i].L-a[j].L));r+=d;}_ r;}I H(S p,W&y,W&n){I f=0;while(1){sprintf(m,"%s%d.wav",p,f++);E h=U(m);if(!h.size())break;W p=G(h);D q=Y(p,y),r=Y(p,n);printf(abs(q-r)<=0.01?"?\n":q<r?"yes\n":"no\n");}}I main(){W y,n;X("train/yes",y);X("train/no",n);H("inputs/",y,n);}

"Ungolfed" (แม้ว่ามันจะยากที่จะเรียกซอร์สโค้ดที่มากกว่า 1.5K golfed):

#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <vector>
#include <math.h>
#include <complex>
#include <endian.h>
#include <functional>

using namespace std;

typedef complex<double> CD;

vector<CD> run_fft(vector<CD>& input, int offset, int size, int dist){
    if(size == 1){
        return vector<CD>(1, input[offset]);
    }
    vector<CD> partLow = run_fft(input, offset, size/2, dist*2),
               partHi  = run_fft(input, offset+dist, size/2, dist*2);

    vector<CD> result(size);
    CD factorBase = exp(CD(0, (inv?2:-2)*M_PI/size)), factor = 1;

    for(int k = 0; k < size/2; k++){
        result[k] = partLow[k] + factor*partHi[k];
        result[k+size/2] = partLow[k] - factor*partHi[k];
        factor *= factorBase;
    }
    return result;
}

vector<CD> fft(vector<CD>& input){
    int N = input.size();
    return run_fft(input, 0, N, 1);
}



const int MAX_BUF = 65536;
const int PWR_TWO = 16384;
const int NUM_CHECK = 75;
int sampling;

char buf[MAX_BUF];
vector<double> read_data(char* filenam){
    FILE* fp = fopen(filenam, "r");
    if(!fp)
        return vector<double>();
    setvbuf(fp, buf, _IOFBF, MAX_BUF);

    fseek(fp, 0, SEEK_END);
    int filesiz = ftell(fp);
    fseek(fp, 128, SEEK_SET);
    filesiz -= 128;

    int insamp = filesiz / 4;
    int freqsamp = 2,
        act_mod = 0;
    sampling = 44100 / freqsamp;
    int inputSize;

    vector<CD> input;

    for(int i = 0; i < insamp; i++){
        signed short int l, r;
        if(fread(&l, 2, 1, fp) != 1) break;
        if(fread(&r, 2, 1, fp) != 1) break;

        double act = 1/32768.0 * (le16toh(l));

        if((++act_mod) == freqsamp){
            inputSize++;
            input.push_back(CD(act,0));
            act_mod = 0;
        }
    }
    inputSize = input.size();

    //printf("%s\n", filenam);
    int numParts = (inputSize+PWR_TWO-1)/PWR_TWO;
    double partDelta = (double)inputSize / numParts, actDelta = 0;
    vector<CD> ndata(PWR_TWO);
    for(int i = 0; i < numParts; i++){
        vector<CD> partInput(PWR_TWO);
        int from = floor(actDelta),
            to = floor(actDelta)+PWR_TWO;

        for(int j = from; j < to; j++)
            partInput[j-from] = input[j];

        vector<CD> partData = fft(partInput);
        for(int j = 0; j < PWR_TWO; j++)
            ndata[j] += partData[j]*(1.0/numParts);
    }


    vector<double> height(PWR_TWO);
    for(int i = 0; i < PWR_TWO; i++)
        height[i] = norm(ndata[i])/PWR_TWO;

    vector<double> nheight(height);
    nheight[0] = (height[0]*0.8 + height[1]*0.1)/0.9;
    nheight[PWR_TWO-1] = (height[PWR_TWO]*0.8 + height[PWR_TWO-1]*0.1)/0.9;
    for(int i = 1; i < PWR_TWO-1; i++)
        nheight[i] = height[i-1]*0.1 + height[i]*0.8 + height[i+1]*0.1;

    fclose(fp);

    return nheight;
}


vector< pair<double,double> > get_highest_peaks(vector<double>& freqData){
    vector< pair<double,int> > peaks;

    for(int i = 3; i < PWR_TWO/2-3; i++){
        if(freqData[i] == *max_element(freqData.begin()+i-3, freqData.begin()+i+4)){
            peaks.push_back(make_pair(freqData[i], i));
        }
    }

    sort(peaks.begin(), peaks.end(), greater< pair<double,int> >());

    vector< pair<double,double> > res;
    for(int i = 3; i < NUM_CHECK+3; i++){
        res.push_back(make_pair((double)(peaks[i].second)/PWR_TWO*sampling, log(peaks[i].first)+10));
    }

    double sum_res = 0;
    for(int i = 0; i < NUM_CHECK; i++)
        sum_res += res[i].second;
    for(int i = 0; i < NUM_CHECK; i++)
        res[i].second /= sum_res;

    /*for(int i = 0; i < NUM_CHECK; i++)
        printf("%12lf %12lf\n", res[i].first, res[i].second);
    printf("\n");*/

    return res;
}


void train(char* dir, const char* type, vector< pair<double,double> >& res){
    vector<double> result(PWR_TWO), height(PWR_TWO);

    int numFile = 0;
    while(true){
        char filenam[256];
        snprintf(filenam, 255, "%s/%s%d.wav", dir, type, numFile);
        height = read_data(filenam);

        if(height.size() == 0)
            break;

        for(int j = 0; j < PWR_TWO; j++)
            result[j] += height[j];

        numFile++;
    }
    fprintf(stderr, "trained %s on %d files\n", type, numFile);

    for(int j = 0; j < PWR_TWO; j++)
        result[j] /= numFile;

    res = get_highest_peaks(result);
}


double dist_ab(vector< pair<double,double> >& A, vector< pair<double,double> >& B){
    double result = 0;
    for(int i = 0; i < NUM_CHECK; i++){
        double add = B[i].second;

        for(int j = 0; j < NUM_CHECK; j++){
            double dist = (B[i].first-A[j].first)/B[i].first;
            if(abs(dist) < 0.015)
                add = min(add, abs(B[i].second - A[j].second));
        }
        result += add;
    }
    return result;
}


void trial(char* dir, const char* pref, vector< pair<double,double> >& yes,
                                        vector< pair<double,double> >& no){
    int numFile = 0;
    int numYes = 0, numDunno = 0, numNo = 0;
    while(true){
        char filenam[256];
        snprintf(filenam, 255, "%s/%s%d.wav", dir, pref, numFile);

        vector<double> height = read_data(filenam);
        if(height.size() == 0)
            break;

        vector< pair<double,double> > peaks = get_highest_peaks(height);


        double distYes = dist_ab(peaks, yes),
               distNo = dist_ab(peaks, no);

        if(abs(distYes-distNo) <= 0.01){
            printf("dunno\n");
            numDunno++;
        } else if(distYes < distNo){
            printf("yes\n");
            numYes++;
        } else {
            printf("no\n");
            numNo++;
        }
        //printf(" (%lf %lf)\n", distYes, distNo);

        numFile++;
    }
}


int main(int argc, char** argv){
    vector< pair<double,double> > yes, no;


    train("train", "yes", yes);
    train("train", "no", no);

    trial("inputs", "", yes, no);
}

ฉันไม่มีความคิดที่เลวร้ายหากมันจะทำงานได้อย่างถูกต้องกับชุดข้อมูลจริง (ฉันคิดว่ามันจะไม่ทำงาน แต่ฉันต้องลอง)

มันทำงานอย่างไร:

  1. ใช้ N = 2 14ตัวอย่างจากช่องทางซ้ายแต่ละอันอยู่ในช่วงเวลาที่เท่ากัน ทำให้เป็นมาตรฐานพวกเขาเพื่อให้ค่า min = 0 และค่าสูงสุด = 1
  2. ประมวลผลโดยใช้ FFT ตอนนี้เราเปลี่ยนจากโดเมนเวลาเป็นโดเมนความถี่ เราอาจจะบอกว่ามือถือของอาร์เรย์ 0 ส่งผลให้เป็น 0Hz เทียบเท่าและ 2 13เซลล์ -1st เป็น 22050Hz เทียบเท่า (นั่นเป็นเพราะผมเอาทุกตัวอย่างอื่น ๆ จาก L ช่องทางเพื่อให้การสุ่มตัวอย่างของฉันคือ 22050Hz แทนความถี่ WAV ของ 44100Hz)
  3. ค้นหาความหมายของสัญญาณดังกล่าวทั้งหมด - เรียกมันว่า "การแจกแจงความถี่เฉลี่ย" ค้นหายอดเขาที่สูงที่สุดของ K ในการแจกแบบนี้ (ที่นี่ K = 75) โดยไม่กี่ตัวแรก ฉันใช้log(mean distribution)+10แล้วทำให้เป็นมาตรฐานเพื่อให้ผลรวมของยอดเขาที่ใหญ่ที่สุดคือ 1
  4. เรามี "การกระจายสูงสุด" สองครั้ง - หนึ่งสำหรับใช่ที่สองสำหรับไม่ใช่หากเรามี WAV เพื่อทดสอบเราแปลงมันในลักษณะเดียวกับก่อน (ขั้นตอนที่ 1, 2, 3) และรับการกระจาย D จากนั้นเราต้อง ตรวจสอบการกระจาย (Y / N) D ที่คล้ายกันมากขึ้น ฉันใช้วิธีการต่อไปนี้: สำหรับแต่ละจุดสูงสุดใน Y / N ให้ลองค้นหาใน D หากเราพบว่า (โดยประมาณ) คะแนนสำหรับจุดสูงสุดนี้คือความแตกต่างที่แน่นอนระหว่างความแข็งแกร่งของ Y / N และ D; ในกรณีตรงกันข้ามมันคือความแข็งแกร่งของ Y / N (เราถือว่ามันเป็นบวกเสมอ) คะแนนดีกว่า (เล็กกว่า) ถ้าผลลัพธ์ที่มีความใกล้ชิด (ผมใช้ 0.01 ความแตกต่างแน่นอน) dunnoเอาท์พุท

ดังที่ฉันได้กล่าวไปแล้วว่าในการทดสอบขั้นสุดท้ายอาจจัดเป็น "ยิ่งแย่กว่าการสุ่ม" แน่นอนฉันหวังว่ามันจะไม่: D

แก้ไข:แก้ไขข้อผิดพลาด (ลืมที่จะปิดไฟล์)


1
คุณโชคดีถ้ามันworse than randomได้ผล คุณอักษรต้องเท่านั้นที่จะเปลี่ยนหนึ่งไบต์ - และมันจะทำdistYes > distNo better than randomหรือจะใช้วิธีอื่นมันค่อนข้างน่าประหลาดใจถ้าคุณเดาได้ว่าผลของการโยนเหรียญไม่ถูกต้อง 100 ครั้งติดต่อกัน! และมันก็ไม่เคยได้ยินมาก่อนว่าอัลกอริธึมเรียบง่ายนั้นทำได้ดีกว่าที่ซับซ้อนกว่าดังนั้น +1 และฉันขอให้คุณโชคดี
blutorange

การทดสอบ ... มันสิ้นสุดลงก่อนกำหนดเนื่องจากEMFILE (Too many open files)... กำลังพยายามแก้ไข ...
Vi

ชนตัวนับไฟล์สูงสุดที่เปิดอยู่ตอนนี้ทำงานแล้ว ผลลัพธ์: ชุดข้อมูลการฝึกอบรม: Accuracy: 983 ‰; Time: 0m27.570s;; ชุดข้อมูลการสอบ: Accuracy: 960 ‰; Time: 0m32.957s. ทำได้ดีมาก
วิ

โอเคฉันแก้ไขสิ่งนี้ มากกว่า 10 ไบต์ :)
mnbvmar

การใช้อย่างไม่น่าเชื่อของ#defines: P
qwr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.