Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Converted WordEmbeddingsTransform into Estimator. - #928

Merged
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator
Sep 19, 2018
Merged

Converted WordEmbeddingsTransform into Estimator.#928
zeahmed merged 7 commits into
dotnet:masterfrom
zeahmed:emb_estimator

Conversation

@zeahmed

Copy link
Copy Markdown
Contributor

This PR fixes#927

@@ -21,10 +23,16 @@
[assembly: LoadableClass(typeof(WordEmbeddingsTransform), null, typeof(SignatureLoadDataTransform),

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof(WordEmbeddingsTransform) [](start = 25, length = 31)

should be typeof(IDataView), typeof(WordEmbeddingTransform) #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not just IDataVIew, but also WordEmbeddingTransform


In reply to: 217929112 [](ancestors = 217929112)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all this confusion, but I was confused as well. First type should be return type of your static Create method. And since you use IDataTransform as return type, you need to use IDataTransform


In reply to: 218249508 [](ancestors = 218249508,217929112)


return
(ref VBuffer<float> dst) =>
if (!_parent.InputType.IsVector)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputType [](start = 29, length = 9)

If you use InputType only here, probably it should be part of Mapper. #Resolved

h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",
ch => new WordEmbeddingsTransform(h, ctx, input));
ch => new WordEmbeddingsTransform(h, ctx));

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch => new WordEmbeddingsTransform(h, ctx)) [](start = 16, length = 42)

Is this recursive call? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, It does not seem to be.


In reply to: 217929300 [](ancestors = 217929300)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like your comment is addressed, right?


In reply to: 218154567 [](ancestors = 218154567,217929300)

IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));
h.CheckValue(input, nameof(input));
return h.Apply("Loading Model",

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return h.Apply("Loading Model", [](start = 12, length = 31)

you don't have to do this Apply magic #Resolved

: base(env, RegistrationName, Contracts.CheckRef(args, nameof(args)).Column,
input, TestIsTextVector)
public WordEmbeddingsTransform(IHostEnvironment env, string inputColumn, string outputColumn,
PretrainedModelKind? modelKind)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? [](start = 11, length = 20)

Nullable type looks weird here.
In argument/columns it's used to setup default value to columns where it's optional, but tend to flatten our structure with ColumnInfo class in each Transformer.

Can you also use ColumnInfo class instead of reusing Column class (Column is mostly for arguments and command line) #Resolved

}

// Factory method for SignatureLoadDataTransform.
public static IDataTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

if you merge with master you can make them private #Resolved

_currentVocab = GetVocabularyDictionary();
_outputType = new VectorType(NumberType.R4, 3 * _currentVocab.Dimension);
Metadata.Seal();
_currentVocab = GetVocabularyDictionary(linesToSkip);

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVocabularyDictionary [](start = 28, length = 23)

Can we move file reading to mapper?
Since you use trivial estimator you basically create transformer in estimator constructor.
Which would force heavy IO processing, and I think purpose of Estimator to be something light weight. #Resolved

label: ctx.Bool.Scalar));

var est = data2.MakeNewEstimator()
.Append(row => row.SentimentText_Features_TransformedText.WordEmbeddings());

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SentimentText_Features_TransformedText.WordEmbeddings() [](start = 35, length = 55)

I think we need to postpone Pigsty extension.
Pigsty suppose to be something convenient, and the whole idea, hey user, run text transform, pull special settings for text transform, take special column, and then apply WordEmbeddings is something I wouldn't call convenient.
I would rather prefer to apply WordEmbeddings for just text column and do all magic inside that extension. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, lets keep it as it is currently implemented.


In reply to: 217930149 [](ancestors = 217930149)

for (int word = 0; word < src.Count; word++)
throw Host.ExceptParam(nameof(input),
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks wrong.

You validate parent in mapper, but throw nameof(input)
#Resolved


var info = Infos[iinfo];
if (!info.TypeSrc.IsVector)
public Mapper(WordEmbeddingsTransform parent, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 16, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputSchema [](start = 66, length = 11)

I think you need to validate somewhere this schema.
You can obtain transformer, but no one guarantee you what it's gonna be applied to same data, or even data with same schema.
We do have some in our base class, but we only check columns with specific names are present, but no one checks types. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetOutputSchema method in Estimator class does that. Is it not sufficient? or need to do it here has well?


In reply to: 217930424 [](ancestors = 217930424)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed...


In reply to: 218168048 [](ancestors = 218168048,217930424)

}
}

public sealed class WordEmbeddingsEstimator : TrivialEstimator<WordEmbeddingsTransform>

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordEmbeddingsEstimator [](start = 24, length = 23)

I'm not certain that this is a trivial estimator, since loading the model file is a fairly elaborate operation. Potentially involving a transfer of some sort of file from Azure, and the actual schema shape does not seem to depend upon this. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the understanding that any transform that does not require training falls into trivial estimator category. That's where WordEmbedding transform falls into. Why do you think its not trivial? what other option are there for this?


In reply to: 218166505 [](ancestors = 218166505)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can always push loading of data to mapper.


In reply to: 218247817 [](ancestors = 218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that pretty much whats happening right now in this transform.


In reply to: 218250223 [](ancestors = 218250223,218247817,218166505)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to non-trivial estimator as there is a data loading involved during training.


In reply to: 218251100 [](ancestors = 218251100,218250223,218247817,218166505)

{
if (!inputSchema.TryFindColumn(colInfo.input, out var col))
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.input);
if (!(col.ItemType is TextType) || col.Kind != SchemaShape.Column.VectorKind.VariableVector)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VariableVector [](start = 93, length = 14)

This is a rather stronger test than the existing TestIsTextVector test. Variable size input vectors can be used of course, but also fixed sized vectors can be used. Unless there is a very strong argument for it, I'd rather not degrade our capability, since there's a fairly straightforward way to apply it to fixed size columns as well. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I relaxed the checking to either be vector or variable length vector.


In reply to: 218167090 [](ancestors = 218167090)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zeahmed. An extra note, while I think the estimator ought to reflect the full capabilities of the transform, I think it is probably fine for the pigsty extension method to remain over varvectors only.


In reply to: 218171027 [](ancestors = 218171027,218167090)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explain the relation between the pretrained model, and an explicitly specified model as via a custom lookup table? My expectation, which may be wrong, is that the two options are mutually exclusive, is it not so? If that is so, then we ought to have two overloads. One for the pre-trained model, the other for the explicitly specified model. #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, through the code it seems like both are mutually exclusive. I have separated out the code for both in different constructors.


In reply to: 218169157 [](ancestors = 218169157)

public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,
string customLookupTable = null)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the proposed most conspicuous part of the public API, we have been tending to write clear documentation for our Pigsty extension methods. #Closed


public static class WordEmbeddingsStaticExtensions
{
public static Vector<float> WordEmbeddings(this Vector<string> input, WordEmbeddingsTransform.PretrainedModelKind modelKind = WordEmbeddingsTransform.PretrainedModelKind.Sswe,

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector [](start = 56, length = 6)

I believe this must be over VarVector, not Vector, is it not so? Indeed given the structure of your test, where you do call this as far as I see, I'm not sure how that test is succeeding, since I imagine it would have failed? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It because the output tokens vector (SentimentText_Features_TransformedText) produced by the TextFeatrizer is of type Vector currently. I set it VarVector and it fails there actually.


In reply to: 218171746 [](ancestors = 218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That sounds like a mistake. The transformed tokenized text will definitely be VarVector<string> not Vector<string>. We ought to fix that there, and in any event not propagate the error there.


In reply to: 218183133 [](ancestors = 218183133,218171746)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Zruty0 might be able to comment more on this.


In reply to: 218219010 [](ancestors = 218219010,218183133,218171746)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am pushing a new commit without fixing it and wil talk to @Zruty0 for more detail.


In reply to: 218219076 [](ancestors = 218219076,218219010,218183133,218171746)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it by getting a VarVector in AssertStatic.

var data2 = dynamicData.AssertStatic(Env, ctx => (
SentimentText_Features_TransformedText: ctx.Text.VarVector,
SentimentText: ctx.Text.Scalar,
label: ctx.Bool.Scalar));

Is this is the correct behavior for this method that it does not complain about getting Vector type when underlying type is VarVector?


In reply to: 218223351 [](ancestors = 218223351,218219076,218219010,218183133,218171746)

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Zeeshan, I think SentimentText_Features_TransformedText that you're asserting from is a variable sized vector, so asserting that it is a VarVector as you have done here seems correct to me. Is it not so? Perhaps I miss the point.

(On the other hand, we ought to have some mechanism to convert a Vector to VarVector, since that seems like something that might be useful sometimes.)


In reply to: 218239184 [](ancestors = 218239184,218223351,218219076,218219010,218183133,218171746)


public static class WordEmbeddingsStaticExtensions
{
/// <include file='doc.xml' path='doc/members/member[@name="WordEmbeddings"]/*' />

@TomFinleyTomFinleySep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[](start = 12, length = 78)

While linking this is probably nice, we should probably also have parameter descriptors, should we not? #Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it too but worried about if its rendered properly. Let me talk to @senja.


In reply to: 218234747 [](ancestors = 218234747)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking to our local expert @sfilipi is never wasted, but we could also try it out... maybe from the test assembly, hit the dots, see what shows up in intellisense. Based on my (almost certainly imperfect) understanding, I think any defined elements are just smooshed together in the output, so even while we can get the import to get the summary and remarks, any params would be rendered without complaint.

I do wonder however what stylecop will make of all that though...


In reply to: 218236334 [](ancestors = 218236334,218234747)

@Zruty0Zruty0 mentioned this pull request Sep 17, 2018

@TomFinleyTomFinley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

{
Host.AssertValue(ctx);
Host.AssertNonEmpty(Infos);
Host.AssertNonEmpty(ColumnPairs);

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it make sense. #Resolved

/// <param name="env">Host Environment.</param>
/// <param name="modelKind">The pretrained word embedding model.</param>
/// <param name="columns">Input/Output columns.</param>
public WordEmbeddingsTransform(IHostEnvironment env, PretrainedModelKind? modelKind, params ColumnInfo[] columns)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PretrainedModelKind? modelKind [](start = 61, length = 30)

can you push modelKind and customLookup table to ColumnInfo class? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not I don't think so because modelKind and customLookupTable are same for all the columns and only needed once.


In reply to: 218250633 [](ancestors = 218250633)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, at least don't make it nullable.


In reply to: 218251539 [](ancestors = 218251539,218250633)

{
Contracts.CheckValue(env, nameof(env));
IHost h = env.Register(RegistrationName);
h.CheckValue(ctx, nameof(ctx));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h.CheckValue(ctx, nameof(ctx)); [](start = 12, length = 31)

I think we have tendency to validate version info for model as well
ctx.CheckAtModel(GetVersionInfo());

Dunno why it's not present here. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, model checking is not there before I started converting into estimator. I will add.


In reply to: 218251360 [](ancestors = 218251360)

/// Instantiates <see cref="WordEmbeddingsTransform"/> using the custom word embedding model by loading it from the file specified by the <paramref name="customLookupTable"/>.
/// </summary>
/// <param name="env">Host Environment.</param>
/// <param name="customLookupTable">Filename for custom word embedding model.</param>

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Filename for custom word embedding model. [](start = 7, length = 86)

This is lookup table, but it's actually a file.
Can we give it proper name? We should leave argument class untouched, but here I would prefer to have something meaningful. #Resolved


_modelKind = modelKind;
_modelFileNameWithPath = EnsureModelFile(env, out _linesToSkip, (PretrainedModelKind)_modelKind);
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath)); [](start = 12, length = 80)

why this is not responsibility of EnsureModelFile? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the code inside EnsureModelFile and found out that if the call is successful it will always have correct FileName otherwise throw error. I am going to remove this check.


In reply to: 218253058 [](ancestors = 218253058)


_modelKind = null;
_modelFileNameWithPath = customLookupTable;
Host.CheckNonWhiteSpace(_modelFileNameWithPath, nameof(_modelFileNameWithPath));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nameof(_modelFileNameWithPath) [](start = 60, length = 30)

nameof(customLookupTable), user don't know about your internal variables. #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be a check on customLookupTable rather than _modelFileNameWithPath. I will fix.


In reply to: 218253183 [](ancestors = 218253183)

=> Create(env, ctx).MakeDataTransform(input);

// Factory method for SignatureLoadRowMapper.
public static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, ISchema inputSchema)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

also can be private #Resolved

}
return GetGetterVec(ch, input, iinfo);
}
Contracts.CheckValue(inputSchema, nameof(inputSchema));

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts [](start = 16, length = 9)

Host which you create in base constuctor #Resolved

{
_inputTypes[i] = inputSchema.GetColumnType(ColMapNewToOld[i]);
if (!_inputTypes[i].IsVector || !_inputTypes[i].ItemType.IsText)
throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", _parent.ColumnPairs[i].input, new VectorType(TextType.Instance).ToString(), _inputTypes[i].ToString());

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basically _parent.CheckInputColumn #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least it should be, and you have slightly different implementations, which I would suggest to move into one.


In reply to: 218255515 [](ancestors = 218255515)

@zeahmedzeahmedSep 17, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the same check. I am wondering if we need to do it here as well because _parent.CheckInputColumn does it already?


In reply to: 218255515 [](ancestors = 218255515)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckInputColumn got called in ITransformer.GetOutputSchema, and this got called during ITransformer.Transform


In reply to: 218257338 [](ancestors = 218257338,218255515)

for (int word = 0; word < src.Count; word++)
throw Host.Except(_parent.ColumnPairs[iinfo].input,
"Text input given, expects a text vector");
}

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you run this check here? why not in constructor? #Resolved

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its not need here anymore as constructor is checking it already.


In reply to: 218256497 [](ancestors = 218256497)

{
}

public WordEmbeddingsEstimator(IHostEnvironment env, WordEmbeddingsTransform transformer)

@Ivanidzo4kaIvanidzo4kaSep 17, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public [](start = 8, length = 6)

this can be private. #Resolved

Comment threadsrc/Microsoft.ML.Transforms/Text/WordEmbeddingsTransform.cs

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@Ivanidzo4kaIvanidzo4ka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@zeahmed
zeahmed merged commit e4987f8 into dotnet:masterSep 19, 2018
@zeahmed
zeahmed deleted the emb_estimator branch January 30, 2019 21:31
@ghostghost locked as resolved and limited conversation to collaborators Mar 29, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert WordEmbeddingsTransform into Estimator.

4 participants

@zeahmed@Ivanidzo4ka@justinormont@TomFinley